How can I optimize this SQL code further to run faster - sql

UPDATE N SET [actType] = 'X'
FROM tableA N
WHERE NOT EXISTS (SELECT 1
FROM tableA O
WHERE O.clientCode = N.clientCode AND
O.[userName] = N.[userName] AND
O.[profile] = N.[profile] AND
O.[rankID] = N.[rankID] - 1
) AND
N.[rankID] NOT IN (SELECT MIN(T.[rankID])
FROM tableA T
WHERE T.[userName] = N.[userName]
)

You can use row_number() with updatable cte :
with cte as (
select N.*, ROW_NUMBER() OVER (PARTITION BY [userName] ORDER BY rankID) AS Seq
from tableA N
)
update c
set c.[actType] = 'X'
from cte c
where seq > 1 and
not exists (SELECT 1
FROM tableA O
WHERE O.clientCode = c.clientCode AND
O.[userName] = c.[userName] AND
O.[profile] = c.[profile] AND
O.[rankID] = c.[rankID] - 1
);
Your syntax suggests SQL Server. So, you can use.

Related

Alternative solution for below SQL Query ,TableMasterID NOT IN take so much time

Need alternative solution for below SQL Query ,TableMasterID NOT IN take so much time, If i remove AND TableMasterID NOT IN
(SELECT DISTINCT c.TableMasterID
FROM ComFinalDataBS as C
WHERE C.ComFileID IN
(SELECT Number FROM fn_SplitInt(#ComFileID,','))) text from below query then getting result in 20 seconds otherwise result getting arround 4 minus.
SELECT A.SubTitleId,TableMasterID from SubTitle as A JOIN ComTableMaster as B ON a.SubTitle = b.TblName AND TableMasterID NOT IN (SELECT DISTINCT c.TableMasterID
FROM ComFinalDataBS as C
WHERE C.ComFileID IN
(SELECT Number FROM fn_SplitInt(#ComFileID,','))) AND B.TableMasterID IN
(SELECT DISTINCT d.TableMasterID
FROM ComData as D
WHERE D.ComFileID IN
(SELECT Number FROM fn_SplitInt(#ComFileID,','))) ORDER BY A.MainTitleID
SELECT A.SubTitleId ,
TableMasterID
FROM SubTitle AS A
JOIN ComTableMaster AS B ON A.SubTitle = B.TblName
WHERE NOT EXISTS ( SELECT 1
FROM ComFinalDataBS C
WHERE TableMasterID = C.TableMasterID
AND C.ComFileID IN (
SELECT Number
FROM MEFCampus..fn_SplitInt(#ComFileID, ',') ) )
AND NOT EXISTS ( SELECT 1
FROM ComData D
WHERE TableMasterID = D.TableMasterID
AND D.ComFileID IN (
SELECT Number
FROM MEFCampus..fn_SplitInt(#ComFileID,
',') ) )
AND B.IsDeleted = 0
ORDER BY MainTitleID
Have you tried storing the result from the fn_split_string() into an indexed temp-table first? It should help the Query Optimizer a lot.
SELECT DISTINCT Number
INTO #ComFileID
FROM dbo.fn_SplitInt(#ComFileID,',')
CREATE UNIQUE CLUSTERED INDEX uq0_ComFileID ON #ComFileID (Number) WITH (FILLFACTOR = 100)
SELECT A.SubTitleId,TableMasterID
FROM SubTitle as A
JOIN ComTableMaster as B
ON a.SubTitle = b.TblName
/*
AND B.TableMasterID NOT IN (SELECT DISTINCT c.TableMasterID
FROM ComFinalDataBS as C
JOIN #ComFileID CFI
ON CFI.Number = C.ComFileID )
*/
AND NOT EXISTS ( SELECT *
FROM ComFinalDataBS as C
JOIN #ComFileID CFI
ON CFI.Number = C.ComFileID
WHERE c.TableMasterID = B.TableMasterID )
/*
AND B.TableMasterID IN (SELECT DISTINCT d.TableMasterID
FROM ComData as D
JOIN #ComFileID CFI
ON CFI.Number = D.ComFileID
*/
AND EXISTS ( SELECT *
FROM ComData as D
JOIN #ComFileID CFI
ON CFI.Number = D.ComFileID
WHERE D.TableMasterID = B.TableMasterID )
ORDER BY A.MainTitleID

SQL Select Into #Temp

I have a complex SQL query that works. It's like
SELECT * FROM Site s
JOIN (
SELECT DISTINCT z.Value FROM Doc z
JOIN (
SELECT x.DocumentID FROM Doc x
JOIN (
SELECT DocumentID, MAX(VERSION) AS VERSION
FROM Doc GROUP BY DocumentID) y ON y.DocumentID = x.DocumentID
WHERE DocumentTypeID = 78 AND MetadataTypeID = 22 AND VALUE > GETDATE() AND y.Version = x.Version
) a ON z.DocumentID = a.DocumentID
WHERE MetadataTypeID = 2
) b ON b.Value = s.SiteID
WHERE SiteID > 0
It does what I want it to do. But when I wrap it in
SELECT * INTO #Temp FROM ()
I get an incorrect syntax near ')'.
I'm confused. I just want to put the results into a temp table so I can do further work on it. Why doesn't it work?
You're missing an alias for subquery.
SELECT * INTO #MyTempTable
FROM
(
SELECT * FROM Site s
JOIN (
SELECT DISTINCT z.Value FROM Doc z
JOIN (
SELECT x.DocumentID FROM Doc x
JOIN (
SELECT DocumentID, MAX(VERSION) AS VERSION
FROM Doc GROUP BY DocumentID) y ON y.DocumentID = x.DocumentID
WHERE DocumentTypeID = 78 AND MetadataTypeID = 22 AND VALUE > GETDATE() AND y.Version = x.Version
) a ON z.DocumentID = a.DocumentID
WHERE MetadataTypeID = 2
) b ON b.Value = s.SiteID
WHERE SiteID > 0
) AS DT
select * into TBL_name from
( SELECT * FROM Site s
JOIN (
SELECT DISTINCT z.Value FROM Doc z
JOIN (
SELECT x.DocumentID FROM Doc x
JOIN (
SELECT DocumentID, MAX(VERSION) AS VERSION
FROM Doc GROUP BY DocumentID) y ON y.DocumentID = x.DocumentID
WHERE DocumentTypeID = 78 AND MetadataTypeID = 22 AND VALUE > GETDATE() AND y.Version = x.Version
) a ON z.DocumentID = a.DocumentID
WHERE MetadataTypeID = 2
) b ON b.Value = s.SiteID
WHERE SiteID > 0)al

Update statement not compiling using alias

This is my update statement which is not being compiled:
Update Documents d
Set
DocumentDate = 1,
LastStatusChangedDateTime = (
Select Top 1 DATEADD(ss,1,StatusChangedDateTime)
From [dbo].[DocumentStatusesHistory] dsh
Where dsh.DocumentID = d.DocumentID
)
Where DocumentID In
(
Select Data From dbo.Split(#DocumentIDs,',')
)
I am unable to use d as an alias. How can I fix this?
How about this?
Update Documents
Set
DocumentDate = 1,
LastStatusChangedDateTime = (
Select Top 1 DATEADD(ss,1,StatusChangedDateTime)
From [dbo].[DocumentStatusesHistory] dsh
Where dsh.DocumentID = d.DocumentID
)
From Documents d
Where DocumentID In
(
Select Data From dbo.Split(#DocumentIDs,',')
)
Add FROM clause:
Update d
Set
DocumentDate = 1,
LastStatusChangedDateTime = (
Select Top 1 DATEADD(ss,1,StatusChangedDateTime)
From [dbo].[DocumentStatusesHistory] dsh
Where dsh.DocumentID = d.DocumentID
)
FROM Documents AS d
...
Try this one :
UPDATE d
SET d.DocumentDate = 1 ,
d.LastStatusChangedDateTime = ( SELECT TOP 1
DATEADD(ss, 1,
StatusChangedDateTime)
FROM [dbo].[DocumentStatusesHistory] dsh
WHERE dsh.DocumentID = d.DocumentID
)
FROM Documents d
WHERE d.DocumentID IN ( SELECT Data
FROM dbo.Split(#DocumentIDs, ',') )

fill a Local #temptable in SQL with multiple Table variables

I'm in SQL Server Management Studio 2008 and I would like to Set Multiple OrderIDs to run them through this query. I heard that I would have to use a TempTable but I'm stuck at how to set Multiple Table variables.
This is the original query I use:
DECLARE #OrderID int
DECLARE #Status int
-- FF nummer
SET #OrderID = 134
-- Huidige status
SET #Status = 4
BEGIN TRANSACTION
UPDATE FF_Task
SET tsk_FK_CurrentStatus = NULL
WHERE (tsk_FK_Order = #OrderID)
UPDATE FF_Order
SET ord_FK_CurrentOrderStatus = NULL
WHERE (ord_PK = #OrderID)
DELETE FROM FF_StatusLog
WHERE (stl_PK IN
(SELECT TOP (1) FF_StatusLog_1.stl_PK
FROM FF_StatusLog AS FF_StatusLog_1 INNER JOIN
FF_Task ON FF_StatusLog_1.stl_FK_Task = FF_Task.tsk_PK
WHERE (FF_Task.tsk_FK_Order = #OrderID)
ORDER BY FF_StatusLog_1.stl_PK DESC))
DELETE
FROM FF_OrderStatusLog
WHERE (osl_Status = #Status) AND (osl_FK_Order = #OrderID)
UPDATE FF_Task
SET
tsk_FK_CurrentStatus = (SELECT TOP (1) FF_StatusLog_1.stl_PK
FROM FF_StatusLog AS FF_StatusLog_1 INNER JOIN
FF_Task ON FF_StatusLog_1.stl_FK_Task = FF_Task.tsk_PK
WHERE (FF_Task.tsk_FK_Order = #OrderID)
ORDER BY FF_StatusLog_1.stl_PK DESC)
WHERE (tsk_FK_Order = #OrderID)
UPDATE FF_Order
SET ord_FK_CurrentOrderStatus = (SELECT TOP 1 osl_Status FROM
FF_OrderStatusLog WHERE (osl_FK_Order = #OrderID) ORDER BY osl_CreationDateTime DESC)
WHERE (ord_PK = #OrderID)
COMMIT TRANSACTION
Thank you.
You can use table variable or temp table
Also in SQLServer2008+ you can passing table-valued parameters to SPs and UDFs.A table-value parameter allows you to pass rows of data to your SPs and UDFs in tabular format. To create a table-valued parameter you must first create a table type that defines your table structure.
DECLARE #TableOfParemeters TABLE(OrderID int, Status int)
INSERT #TableOfParemeters
VALUES(134, 4),
(135, 5)
BEGIN TRANSACTION
UPDATE FF_Task
SET tsk_FK_CurrentStatus = NULL
WHERE tsk_FK_Order IN (SELECT OrderID FROM #TableOfParemeters)
UPDATE FF_Order
SET ord_FK_CurrentOrderStatus = NULL
WHERE ord_PK IN (SELECT OrderID FROM #TableOfParemeters)
;WITH cte AS
(
SELECT *, ROW_NUMBER() OVER(PARTITION BY stl_PK ORDER BY stl_PK DESC) AS rn
FROM FF_StatusLog stl INNER JOIN FF_Task ff ON stl.stl_FK_Task = ff.tsk_PK
WHERE ff.tsk_FK_Order IN (SELECT OrderID FROM #TableOfParemeters)
)
DELETE cte
WHERE rn = 1
DELETE
FROM FF_OrderStatusLog
WHERE EXISTS (
SELECT 1
FROM #TableOfParemeters t
WHERE osl_Status = t.Status AND osl_FK_Order = t.OrderID
)
;WITH cte AS
(
SELECT stl.stl_PK, ff.tsk_FK_CurrentStatus,
ROW_NUMBER() OVER(PARTITION BY stl_PK ORDER BY stl_PK DESC) AS rn
FROM FF_StatusLog stl INNER JOIN FF_Task ff ON stl.stl_FK_Task = ff.tsk_PK
WHERE ff.tsk_FK_Order IN (SELECT OrderID FROM #TableOfParemeters)
)
UPDATE cte
SET tsk_FK_CurrentStatus = stl_PK
WHERE rn = 1
;WITH cte AS
(
SELECT o.ord_FK_CurrentOrderStatus, l.osl_Status,
ROW_NUMBER() OVER(PARTITION BY osl_Status ORDER BY osl_CreationDateTime DESC) AS rn
FROM FF_Order o INNER JOIN FF_OrderStatusLog l ON o.ord_PK = l.osl_FK_Order
WHERE l.osl_FK_Order IN (SELECT OrderID FROM #TableOfParemeters)
)
UPDATE cte
SET tsk_FK_CurrentStatus = osl_Status
WHERE rn = 1
COMMIT TRANSACTION

How to add 2 numbers in sql Select clause?

I have this query:
Select
Count(DocumentID)
From
Documents d
Inner Join
Accounts a on a.AccountID = d.CreatedByAccountID
Where
a.FeeExempt = 1
Or
(Select
Case
When a.OrganizationTypeID = 1 Or a.OrganizationTypeID = 2
Then 0
Else EFileFee
End
From ITypes
Where ITypeID = d.ITypeID
+
Select 100 --just to test
) <= 0
How can I make this query compile? Basically I want to do 2 selects and check if addition of both of them is less than 0 or not. But obviously at the moment the query is incorrect and won't compile.
Do you want this:
. . ..
(select sum(val)
from ((Select (Case When a.OrganizationTypeID = 1 Or a.OrganizationTypeID = 2 Then 0 Else EFileFee End) as val
From ITypes
Where ITypeID = d.ITypeID
) union all
(Select 100 --just to test
)
) t
) <= 0