WITH-AS statement with declare and set - sql-server

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...

Related

Row number with len in 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;

Reversing the sort order of a cte

In Microsoft SQL Server, the following works, but produces:
,Son,Dad,Granddad,Great Granddad
whereas I need it to say:
Great Granddad,Granddad,Dad,Son
declare #Family Table(
ID Int Identity(100,1) Primary Key
,Person varchar(128)
,ParentID Int default 0
)
insert into #Family(Person,ParentID) values('Great Granddad',0)
insert into #Family(Person,ParentID) values('Granddad',100)
insert into #Family(Person,ParentID) values('Dad',101)
insert into #Family(Person,ParentID) values('Son',102)
DECLARE #ID Int = 103
;with cte1 as (
select
#ID AS cteID
,ID
,ParentID
,Person as ctePerson
from #Family
where ID = #ID -- this is the starting point you want in your recursion
UNION ALL
select #ID, F.ID, F.ParentID, F.Person
from #Family F
join cte1 P on P.ParentID = F.ID -- this is the recursion
)
-- cte2 can reverse the sort order based on something built in (OVER?)
-- ROW_NUMBER() OVER(ORDER BY ? DESC) AS Row
,cte3 AS(
select ID as cte3ID,(
SELECT ',' + ctePerson
FROM cte1
WHERE cteID = F.ID
FOR XML PATH ('')
) as People
from #Family F
where ID=#ID
)
SELECT * FROM CTE3
I would not order the result of a recursive CTE by using another CTE, as the results of CTEs are semantically tables, and therfore the order is not guaranteed. Instead order when selecting from a CTE, just als like with normal tables.
I would suggest to insert a field representing the level or relationship and order by that:
;with cte1 as (
select
#ID AS cteID
,ID
,ParentID
,Person as ctePerson
,0 lvl -- starting level with 0
from #Family
where ID = #ID -- this is the starting point you want in your recursion
UNION ALL
select #ID, F.ID, F.ParentID, F.Person
, lvl + 1 -- increase level by 1
from #Family F
join cte1 P on P.ParentID = F.ID -- this is the recursion
)
,cte3 AS(
select ID as cte3ID,STUFF(( -- stuff removes the first ','
SELECT ',' + ctePerson
FROM cte1
WHERE cteID = F.ID
ORDER by lvl DESC -- order by level DESC to start with latest ancestor
FOR XML PATH ('')
), 1, 1, '') as People
from #Family F
where ID=#ID
)
SELECT * FROM CTE3

Using Split with CTE to get Even and Odd Indexed value in sql

I do have a list of data having members Choice and IsRightAnswer for MCQ. I want to send this list to stored procedure that I did by having ',' as delimiter. Now in stored procedure I want to have choice and IsRightAnswer into two seperate table which I tried to do by separating them by odd and even index. I got stuck into ORDERBY condition of ROW_NUMBER. How can I do it efficiently?
DECLARE #temp table(Choice nvarchar(500), [rowCount] int IDENTITY(1,1))
DECLARE #tempIsRight table(IsRight bit, [rowCount] int IDENTITY(1,1))
;with tempChoice
as
(
select *,ROW_NUMBER() OVER (ORDER BY '') AS RowNumber
from dbo.Split(#Choice,',')
)
INSERT INTO #temp select * from tempChoice where RowNumber%2=0
;with tempIsRight
as
(
select *,ROW_NUMBER() OVER (ORDER BY '') AS RowNumber
from dbo.Split(#Choice,',')
)
INSERT INTO #tempIsRight select * from tempIsRight where RowNumber%2!=0
You can give dummy for ORDER BY like - (SELECT 1)
DECLARE #temp table(Choice nvarchar(500), [rowCount] int IDENTITY(1,1))
DECLARE #tempIsRight table(IsRight bit, [rowCount] int IDENTITY(1,1))
;with tempChoice
as
(
select *,ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS RowNumber
from dbo.Split(#Choice,',')
)
INSERT INTO #temp select * from tempChoice where RowNumber%2=0
;with tempIsRight
as
(
select *,ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS RowNumber
from dbo.Split(#Choice,',')
)
INSERT INTO #tempIsRight select * from tempIsRight where RowNumber%2!=0

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