Row number with len in SQL Server - sql-server

I want to take the length of a specific row and show this substring, but I'm not getting luck, can somebody help me I was trying something like this:
declare #teste int
declare #rows int
select #rows = (select COUNT(DS_Description) from IMPL_Activities)
while #rows > 0
begin
--select #test = (select LEN(DS_Description), ROW_NUMBER() over (order by ID_Deployment) rn
--from IMPL_Activities where rn in (#rows))
select
#test = (select *
from
(select
ROW_NUMBER() over(order by ID_Deployment) rn
from IMPL_Activities) as imp
where rn in (#rows)
select LEN(DS_Description) from IMPL_Activities where rn in (#rows))
set #rows = #rows - 1
select SUBSTRING(DS_Description, 1, #test)
from IMPL_Activities
end
But can't save the number of character that have this column in that row, I don't know if did you understood, but comments, or edit, to make sure that everyone will understand.
Thanks

No cursor necessary, is this what you want?
SELECT
SUBSTRING(DS_Description,LEN(DS_Description)/2,1)
FROM
IMPL_Activities;

Related

SQL Server subquery with top and max returning error

Why doesn't this code work? I get this error
Error near ')'
on the last line. I cannot see where I made a syntax error (this is for SQL Server 2017).
DECLARE #NumRows INT;
SELECT #NumRows = COUNT(*) / 2
FROM SAMA;
SELECT MAX(NoMonths)
FROM
(SELECT TOP(#NumRows) NoMonths
FROM SAMA
ORDER BY NoMonths ASC)
What the query is trying to do, is to find a max of top N rows, and the N is defined in the variable.
Without MAX, the subquery works and returns N rows. But when I add MAX, it fails.
You have to set a table alias:
DECLARE #NumRows INT;
SELECT #NumRows = COUNT(*) / 2 FROM SAMA;
SELECT MAX(NoMonths)
FROM (
SELECT TOP(#NumRows) NoMonths
FROM SAMA
ORDER BY NoMonths ASC
) table_alias
You need to have a table alias
DECLARE #NumRows INT;
SELECT #NumRows = COUNT(*) / 2 FROM SAMA;
SELECT MAX(NoMonths)
FROM (SELECT TOP(#NumRows) NoMonths FROM SAMA ORDER BY NoMonths ASC) sama_alias

WITH-AS statement with declare and set

I'm a newbie of sql-server and I've been learning sql queries about with-as and declare and set.
I have a question to make my query short.
DECLARE #MaxID int;
SET #MaxID = (SELECT MAX(rowNumber) FROM (
SELECT ROW_NUMBER() OVER(ORDER BY NoWkOrd ASC) AS rowNumber, a, b FROM
t
) t1) ;
SELECT rowNumber, NoWkOrd, CdEquip, DtWkOrd
FROM (
SELECT ROW_NUMBER() OVER(ORDER BY NoWkOrd ASC) AS rowNumber, a, b
FROM t
) t1
WHERE rowNumber > #MaxID
This is an orignal query and I want to make this short by using with-as cuz two query inside of from is used twice at the same time.
DECLARE #MaxID int;
WITH t1
AS (
SELECT ROW_NUMBER() OVER(ORDER BY NoWkOrd ASC) AS rowNumber, a, b
FROM t
)
SET #MaxID = (SELECT MAX(rowNumber) FROM (t1) ;
SELECT rowNumber, NoWkOrd, CdEquip, DtWkOrd
FROM t1
WHERE rowNumber > #MaxID
But here's an error around SET but i'm still struggling with what is wrong...

MS SQL pagination and grouping

I need help, because I'm struggling on how to page through and limiting that each page just show one process at a time. I have tried so many things and my brain got fried. Help........
So if the #PageNum = 1 and #Pagesize = 10 and if the first process has 7 rows; first page will show 7 rows of the first process (exactly what I want).
Now if the user chooses #PageNum = 2 and #Pagesize is 10 and the second process has 11. I want it to show the top 10 of this next process.
Currently it's showing only the last 8 of the second process.
I simplified the SQL to remove business information and then just to show the list of what I'm dealing with:
/*
notes:
Parameters passed in are #PageNum and #PageSize
#PageNum is which page they user goes to
#PageSize is the max number of rows to show
*/
DECLARE #StartRow int, #EndRow int
SET #StartRow = (#PageNum -1) * #PageSize +1;
SET #EndRow = #PageNum * #PageSize;
WITH ProcessestoPageThru AS
(Select Name,
ProcessId,
ROW_NUMBER() OVER(ORDER BY Name, ProcessId, ) as RowNo,
COUNT(Name) OVER() as RowCnt
from a whole bunch of tables
where a whole bunch of criteria
)
SELECT * INTO #tmp_ProcessestoPageThru
From ProcessestoPageThru
Where RowNo BETWEEN #StartRow AND #EndRow
Declare #ProcessID int
--Get the top ProcessID, We are only going to display one Process at a time
Select Top 1 #ProcessID = ProcessId
From #tmp_ProcessestoPageThru
Select *
from #tmp_ProcessestoPageThru
Where ProcessId = #ProcessId
Please see example attached:
Example
Try with other sample data.
If it is slow with real data then let me know with details.
i) you are only passing parameter like #Pageinde,#Pagesize apart from other search criteria.
ii)TotalPage is the number of pages that you get and have to ppolate your page accirdingly.forget the old calculation.
iii) rowcnt is not required.
declare #Pageindex int=1
declare #Pagesize int=10
declare #t table(processid int, rowcnt int)
insert into #t values(1,345),(1,345),(1,345),(1,345),(1,345),(1,345),(1,345)
,(1,345),(1,345),(1,345),(1,345),(1,345)
,(2,345),(2,345),(2,345),(2,345),(2,345),(2,345),(2,345),(2,345)
,(2,345),(2,345),(2,345),(3,345),(3,345)
;with CTE as
(
select *
,DENSE_RANK()over(order by processid) rownum
--,ROW_NUMBER()over(partition by processid order by processid) rownum1
,ROW_NUMBER()over(order by processid) rownum2
from #t
)
,CTE1 AS(
select *,
case when (rownum2/cast(#Pagesize as FLOAT))=1 then (rownum2/#Pagesize )
ELSE (rownum2/#Pagesize )+rownum END PageIndex
from cte c
)
select processid,rownum2
,(select max(PageIndex) from cte1) TotalPage
from cte1
where PageIndex=#Pageindex
You also need to do a PARTITION BY on ProcessId to display the results by that column value. Here is the code that may help you to do that.
;WITH ProcessestoPageThru AS
(
Select Name,
ProcessId,
ROW_NUMBER() OVER( PARTITION BY ProcessId ORDER BY Name, ProcessId ) as RowNo,
COUNT(Name) OVER() as RowCnt
FROM processes
)
SELECT Name,
ProcessId,
RowNo,
RowCnt
From ProcessestoPageThru
Where RowNo BETWEEN #StartRow AND #EndRow
AND ProcessId = #ProcessID

SQL Server stored procedure with ROW_NUMBER

I am try to create a stored procedure that takes an index where to start, max rows to show and a location. It them returns a list of HouseID and the location, but I also want it to include the "name of the house" from another table called dbo.House which has a HouseId to link it to the Location. How would I go about adding the second table.
Thanks,
CREATE PROCEDURE dbo.basicHouseSearch
#StartIndex int,
#MaxRows int,
#HouseLocation NVarChar(50)
AS
BEGIN
SET NOCOUNT ON;
Select
Location.HouseID, CityTown
FROM
(SELECT
ROW_NUMBER() OVER (ORDER by Location.HouseID) as RowNumber,
Location.HouseID,
CityTown
FROM dbo.Location) Location
WHERE
RowNumber >= #StartIndex
AND ROWNUMBER < (#StartIndex + #MaxRows)
END
GO
I re wrote your code so it uses OFFSET/FETCH (I think that it's clearer that way):
SELECT L.HouseID,
L.CityTown,
H.Name [Name of the house]
FROM dbo.Location L
LEFT JOIN dbo.House H
ON L.HouseID = H.HouseID
ORDER BY L.HouseID
OFFSET #StartIndex ROWS FETCH NEXT #MaxRows ONLY
(Requires Sql Server 2012 or later)
I re wrote your code so it uses a CTE (I think that it's clearer that way):
;WITH CTE AS
(
SELECT RowNumber = ROW_NUMBER() OVER (ORDER by L.HouseID),
L.HouseID,
L.CityTown,
H.Name [Name of the house]
FROM dbo.Location L
LEFT JOIN dbo.House H
ON L.HouseID = H.HouseID
)
SELECT *
FROM CTE
WHERE RowNumber >= #StartIndex
AND RowNumber < (#StartIndex + #MaxRows)

SQL Server Full Text Search Very Slow

I have a stored procedure that searches a table which has about 200000+ rows with full text FREETEXT.
Here is the basics of it:
declare #searchKey varchar(150)
if #searchKey Is Null OR LEN(#searchKey)=0
Set #searchKey='""';
Set #searchKey='car';
declare #perPage int
Set #perPage=40
declare #pageNo int
Set #pageNo=1
declare #startIndex int,#endIndex int;
Set #startIndex=#perPage*#pageNo-#perPage+1;
Set #endIndex=#perPage*#pageNo;
Select totalItems
--i pull other colums as well
from (
Select Row_Number() over(order by CreateDate DESC) As rowNumber
,COUNT(*) OVER() as totalItems
--other columns are pulled as well
from MyTable P
Where
#searchKey='""'
OR FreeText((P.Title,P.Description),#searchKey)
) tempData
--where rowNumber>=#startIndex AND rowNumber<=#endIndex
where
rowNumber>=CASE WHEN #startIndex>0 AND #endIndex>0 THEN #startIndex ELSE rowNumber END
AND rowNumber<=CASE WHEN #startIndex>0 AND #endIndex>0 THEN #endIndex ELSE rowNumber END
order by rowNumber
The problem is its running slower then i would like it. Its taking about 3 seconds to load the page. Same page was loading in less then 1 sec when i was using like operator.
In my experience, full text index functions do not work well in a clause that contains an "OR" operator. I have had to get the same behavior by adjusting my query to use a UNION. Try this and see if you can get better performance.
declare #searchKey varchar(150)
if #searchKey Is Null OR LEN(#searchKey)=0
Set #searchKey='""';
Set #searchKey='car';
declare #perPage int
Set #perPage=40
declare #pageNo int
Set #pageNo=1
declare #startIndex int,#endIndex int;
Set #startIndex=#perPage*#pageNo-#perPage+1;
Set #endIndex=#perPage*#pageNo;
Select totalItems
--i pull other colums as well
from (
Select Row_Number() over(order by CreateDate DESC) As rowNumber
,COUNT(*) OVER() as totalItems
--other columns are pulled as well
from
(
select * from
MyTable A
Where
#searchKey='""'
UNION
select * from MyTable B
where FreeText((B.Title,B.Description),#searchKey)
) as innerTable
) tempData
--where rowNumber>=#startIndex AND rowNumber<=#endIndex
where
rowNumber>=CASE WHEN #startIndex>0 AND #endIndex>0 THEN #startIndex ELSE rowNumber END
AND rowNumber<=CASE WHEN #startIndex>0 AND #endIndex>0 THEN #endIndex ELSE rowNumber END
order by rowNumber

Resources