Find Duplicate Phones using cte by comparing against other groups - sql

I am trying to determine how many duplicate work phones I can find in Group 94 by comparing against all other groups that are active.
Contacts are grouped using GroupId
The ContactTable Only contains ids and NOT Phones
The DetailedContactTable contains phones
The ContactSummaryTable contains Group status
The sql is working by setting rownumber for each duplicate Workphone > 1.
The problem is that is setting the rownumber > 1 for all groups except for 94. I need to know 94 first and foremost. Any idea how I set rownumber > 1 for duplicates in GroupId 94 first?
DECLARE #GroupID Int
SET #GroupID = 94
;WITH cte AS
(
SELECT ROW_NUMBER() OVER (PARTITION BY d.WorkPhone ORDER BY c.id DESC)
AS rownumber
,d.WorkPhone
,c.id
,GroupID
FROM ContactTable c
INNER JOIN DetailedContactTable d
ON c.DetailedContactId = d.id
WHERE c.GroupID IN
(
SELECT id
FROM ContactSummaryTable WHERE id = #GroupID
OR GroupActive = 1
)
AND NOT d.WorkPhone IS NULL
AND d.WorkPhone <> ''
)
SELECT * FROM cte WHERE rownumber > 1
ORDER BY GroupID;

DECLARE #GroupID INT;
SET #GroupID = 94;
WITH BaseGroup
AS
(
SELECT c.GroupID
,d.WorkPhone
,c.id ContactID
FROM ContactTable c
INNER JOIN DetailedContactTable d ON c.DetailedContactId = d.id
WHERE c.GroupID = #GroupID
AND NOT d.WorkPhone IS NULL
AND d.WorkPhone <> ''
),
OtherGroups
AS
(
SELECT
d.WorkPhone
FROM ContactTable c
INNER JOIN DetailedContactTable d ON c.DetailedContactId = d.id
WHERE c.GroupID <> #GroupID
AND NOT d.WorkPhone IS NULL
AND d.WorkPhone <> ''
AND EXISTS (
SELECT *
FROM ContactSummaryTable WHERE id = c.GroupID
AND GroupActive = 1)
)
SELECT a.*
FROM BaseGroup a
INNER JOIN OtherGroups b ON a.WorkPhone = b.WorkPhone
ORDER BY a.WorkPhone
or
SELECT a.*, CASE WHEN b.WorkPhone IS NULL THEN 'no duplicate' ELSE 'duplicate' END [Status]
FROM BaseGroup a
LEFT JOIN OtherGroups b ON a.WorkPhone = b.WorkPhone
ORDER BY a.WorkPhone

Related

Use CTE in SQL to flag DUPLICATES and reference in sub-query

So I have the following CTE:
with dupeinv AS (
select * from (
select
tci.t_idoc,
tci.t_idat,
ROW_NUMBER() OVER (partition by tci.t_idoc ORDER BY tci.t_idoc, tci.t_idat DESC) as rn
from [ln106].[dbo].tcisli305100 tci
) as t
where t.rn = 1
)
There are duplicates in the above table ([ln106].[dbo].tcisli305100) , hence the CTE to get single values. I want to format just these values in the below query (prefixed with ---)
select 'JCI' as BU,
RTRIM(LTRIM(cl.t_orno)) AS SALES_ORDER_NUMBER
, cl.t_pono AS SALES_ORDER_LINE_NUMBER
, CONCAT(cl.t_shpm, cl.t_pono, cl.t_idoc) AS SHIPPING_RECORD_ID
,CASE WHEN cl.t_dqua = 0 or cl.t_dqua is null THEN cl.t_amti ELSE
cl.t_amti / cl.t_dqua END AS AR_INVOICE_LINE_ITEM_PRICE_LOCAL
, cl.t_line AS AR_INVOICE_LINE_NUMBER
, cl.t_dqua AS AR_INVOICE_LINE_ITEM_QUANTITY
--- , concat(dupeinv.t_idoc,'|',format(dupeinv.t_idat,'MMddyyyy') ---
,ci.t_ccur AS AR_INVOICE_CURRENCY
, ci.t_idat AS AR_INVOICE_DATE
FROM [ln106].[dbo].tcisli310100 cl
LEFT JOIN [ln106].[dbo].tcisli305100 ci ON cl.t_idoc = ci.t_idoc
LEFT JOIN t di on cl.t_doc = di_t_doc
LEFT JOIN (SELECT t_orno,t_pono FROM [ln106].[dbo].ttdsls401100 WHERE t_oltp <> 1 group by t_orno,t_pono) as l --Jed 10162020 Changed the join to prevent duplicate records
ON l.t_orno=cl.t_orno COLLATE SQL_Latin1_General_CP1_CI_AS AND l.t_pono=cl.t_pono
LEFT JOIN dupeinv tci on cl.r_idoc = ci.t_doc
WHERE ci.t_idat > '2017'
Query doesn't like me referencing it in the main query. Can anyone help, or suggest a better idea?
Your final query should look something like this:
WITH dupeinv AS
(SELECT *
FROM
(SELECT tci.t_idoc,
tci.t_idat,
ROW_NUMBER() OVER (PARTITION BY tci.t_idoc
ORDER BY tci.t_idoc,
tci.t_idat DESC) AS rn
FROM [ln106].[dbo].tcisli305100 tci) AS t
WHERE t.rn = 1 )
SELECT 'JCI' AS BU,
RTRIM(LTRIM(cl.t_orno)) AS SALES_ORDER_NUMBER ,
cl.t_pono AS SALES_ORDER_LINE_NUMBER ,
CONCAT(cl.t_shpm, cl.t_pono, cl.t_idoc) AS SHIPPING_RECORD_ID ,
CASE
WHEN cl.t_dqua = 0
OR cl.t_dqua IS NULL THEN cl.t_amti
ELSE cl.t_amti / cl.t_dqua
END AS AR_INVOICE_LINE_ITEM_PRICE_LOCAL ,
cl.t_line AS AR_INVOICE_LINE_NUMBER ,
cl.t_dqua AS AR_INVOICE_LINE_ITEM_QUANTITY ,
concat(dupeinv.t_idoc,
'|',
format(dupeinv.t_idat, 'MMddyyyy')) ,
ci.t_ccur AS AR_INVOICE_CURRENCY ,
ci.t_idat AS AR_INVOICE_DATE
FROM [ln106].[dbo].tcisli310100 cl
LEFT JOIN [ln106].[dbo].tcisli305100 ci ON cl.t_idoc = ci.t_idoc
LEFT JOIN t di ON cl.t_doc = di_t_doc
LEFT JOIN
(SELECT t_orno,
t_pono
FROM [ln106].[dbo].ttdsls401100
WHERE t_oltp <> 1
GROUP BY t_orno,
t_pono) AS l --Jed 10162020 Changed the join to prevent duplicate records
ON l.t_orno=cl.t_orno COLLATE SQL_Latin1_General_CP1_CI_AS
AND l.t_pono=cl.t_pono
LEFT JOIN dupeinv tci ON cl.r_idoc = ci.t_doc
WHERE ci.t_idat > '2017'

SQL Server query slow - how do optimize it?

I would like some help to optimize this query to be faster.
This query produces a view that latter will be showed in a table in a website.
This query is slow, and I am trying to make it faster.
The only thing I tried till now is to reduce the amount of columns I retrieve for the table.
This is the query:
SELECT TOP (100) PERCENT Id, MAX(BusinessTitle) AS BusinessTitle, MAX(ClientName) AS ClientName, MAX(ClientType) AS Type, MAX(CreatedWhen) AS CreatedWhen, MAX(CASE WHEN C.[CreatedBy] IS NULL
THEN 'Client' ELSE 'Admin' END) AS CreatedBy, CAST(MAX(CASE WHEN C.IsDisabled = 1 THEN 1 ELSE 0 END) AS BIT) AS IsDisabled, MAX(ReferenceSource) AS ReferenceSource, MAX(OtherReferenceSource)
AS OtherReferenceSource, MAX(Address) AS Address,
(SELECT MAX(T.FirstName + ' ' + T.LastName) AS Expr1
FROM dbo.ApplicationUsers AS A INNER JOIN
dbo.Therapists AS T ON A.UserName = MAX(C.ClientName) AND A.Id = T.ApplicationUserId) AS ClientAdmin,
(SELECT MAX(A.Email) AS Expr1
FROM dbo.ApplicationUsers AS A INNER JOIN
dbo.Therapists AS T ON A.UserName = MAX(C.ClientName) AND A.Id = T.ApplicationUserId) AS Email,
(SELECT MAX(Name) AS Expr1
FROM dbo.Cities AS CY
WHERE (Id = MAX(C.CityId))) AS City,
(SELECT COUNT(*) AS Expr1
FROM dbo.Patients AS P
WHERE (ClientId = C.Id)) AS TotalPatientCount,
(SELECT COUNT(*) AS Expr1
FROM dbo.Patients AS P
WHERE (ClientId = C.Id) AND (IsDeleted = 0) AND (IsDisabled = 0)) AS ActivePatientCount,
(SELECT MAX(CreatedWhen) AS Expr1
FROM dbo.Patients AS P
WHERE (ClientId = C.Id)) AS LastPatientAddition,
(SELECT COUNT(*) AS Expr1
FROM dbo.Treatments AS T
WHERE (ClientId = C.Id)) AS TotalTreatmentCount,
(SELECT MAX(CreatedWhen) AS Expr1
FROM dbo.Treatments AS T
WHERE (ClientId = C.Id)) AS LastTreatmentAddition,
(SELECT COUNT(*) AS Expr1
FROM dbo.Therapists AS T
WHERE (ClientId = C.Id)) AS TotalTherapistCount,
(SELECT COUNT(*) AS Expr1
FROM dbo.Therapists AS T INNER JOIN
dbo.ApplicationUsers AS A ON T.ClientId = C.Id AND T.ApplicationUserId = A.Id
WHERE (A.IsDeleted = 0) AND (A.IsDisabled = 0)) AS ActiveTherapistCount,
(SELECT MAX(A.CreatedWhen) AS Expr1
FROM dbo.Therapists AS T INNER JOIN
dbo.ApplicationUsers AS A ON T.ClientId = C.Id AND T.ApplicationUserId = A.Id) AS LastTherapistAddition,
(SELECT MAX(A.LastLoginDate) AS Expr1
FROM dbo.Therapists AS T INNER JOIN
dbo.ApplicationUsers AS A ON T.ClientId = C.Id AND T.ApplicationUserId = A.Id
WHERE (A.LastLoginDate IS NOT NULL)) AS TherapistLastLoginDate, CAST((CASE WHEN
((SELECT COUNT(S.[Id])
FROM [dbo].[ClientSubscriptions] AS S
WHERE ((S.[ClientId] = C.[Id]) AND (S.[IsDeleted] = 0) AND ((S.[SubscriptionEnd] IS NULL) OR
(S.[SubscriptionEnd] > GETDATE())))) > 0) THEN 1 ELSE 0 END) AS BIT) AS HasActiveSubscription,
(SELECT MAX(SubscriptionEnd) AS Expr1
FROM dbo.ClientSubscriptions AS S
WHERE (ClientId = C.Id) AND (IsDeleted = 0) AND (SubscriptionEnd IS NULL OR
SubscriptionEnd > GETDATE())) AS LastValidSubscriptionEnd, CAST((CASE WHEN
((SELECT COUNT(S.[Id])
FROM [dbo].[ClientSubscriptions] AS S
WHERE ((S.[ClientId] = C.[Id]) AND (S.[IsDeleted] = 0) AND ((S.[SubscriptionEnd] IS NULL) OR
(S.[SubscriptionEnd] > GETDATE())) AND (S.[Id] <>
(SELECT MIN(S2.[Id])
FROM [dbo].[ClientSubscriptions] AS S2
WHERE ((S2.[ClientId] = C.[Id]) AND (S2.[IsDeleted] = 0)))))) > 0) THEN 1 ELSE 0 END) AS BIT) AS IsPayingCustomer, COALESCE
((SELECT MAX(MonthlyPrice) AS Expr1
FROM dbo.ClientSubscriptions AS S
WHERE (ClientId = C.Id) AND (IsDeleted = 0) AND (SubscriptionEnd IS NULL OR
SubscriptionEnd > GETDATE()) AND (MonthlyPrice > 0)), 0.00) AS ActiveSubscriptionMonthlyPrice, MAX(ClientStatus) AS Status, MAX(Phone1) AS Phone, MAX(Phone2) AS Phone2,
(SELECT Code
FROM dbo.DiscountCoupons AS DC
WHERE (Code =
(SELECT TOP (1) DiscountCouponCode
FROM dbo.ClientPayments AS CP
WHERE (ClientId = C.Id)
ORDER BY Id))) AS DiscountCouponCode,
(SELECT IssuedTo
FROM dbo.DiscountCoupons AS DC
WHERE (Code =
(SELECT TOP (1) DiscountCouponCode
FROM dbo.ClientPayments AS CP
WHERE (ClientId = C.Id)
ORDER BY Id))) AS DiscountCouponIssuedTo,
(SELECT ClientDiscount
FROM dbo.DiscountCoupons AS DC
WHERE (Code =
(SELECT TOP (1) DiscountCouponCode
FROM dbo.ClientPayments AS CP
WHERE (ClientId = C.Id)
ORDER BY Id))) AS DiscountCouponClientDiscount, COALESCE
((SELECT COUNT(Id) AS Expr1
FROM dbo.ClientFiles AS F
WHERE (ClientId = C.Id)), 0) AS TotalFilesCount, COALESCE
((SELECT SUM(FileSize) AS Expr1
FROM dbo.ClientFiles AS F
WHERE (ClientId = C.Id)), 0) / 1048576.0 AS TotalFilesSize, CAST(MAX(CASE WHEN C.CrmEnded = 1 THEN 1 ELSE 0 END) AS BIT) AS CrmEnded, MAX(CrmStatus) AS CrmStatus, MAX(CrmUnuseReason)
AS CrmUnuseReason,
(SELECT COUNT(1) AS Expr1
FROM dbo.Tipulog_Crm_Calls_new AS CC
WHERE (Cust_id = C.Id)) AS CrmCallCount
FROM dbo.Clients AS C
WHERE (IsDeleted = 0)
GROUP BY Id
I will add a second answer, which is the complete sql. This has of course not been tested as we have no access to your data, but I think you should be able to debug it yourself. There are many pointers in this code that should show you how to go.
The basic thing is to take out all of the correlated queries and put them as subqueries. The only reason to do this is all the Max/Min you use - I would look at those as if they are not necessary depending on your data then you should take them out and join to the tables directly. All the subqueries are left joins - again make them normal joins if you can depending on your data.
Also took out the outside group by Id, as 99% sure this is not necessary, as is the Top 100% bit.
SELECT BusinessTitle, ClientName, ClientType AS Type, CreatedWhen,
CASE WHEN C.[CreatedBy] IS NULL THEN 'Client' ELSE 'Admin' END) AS CreatedBy,
CAST(CASE WHEN C.IsDisabled = 1 THEN 1 ELSE 0 END AS BIT) AS IsDisabled,
ReferenceSource, OtherReferenceSource, Address,
ApplicationByName.FullName AS ClientAdmin,
ApplicationByName.Email AS Email,
Cities.Name AS City,
Patients.TotalPatientCount,
Patients.ActivePatientCount,
Patients.LastPatientAddition,
Treatments.TotalTreatmentCount,
Treatments.LastTreatmentAddition,
Therapists.TotalTherapistCount,
Therapists.ActiveTherapistCount,
Therapists.LastTherapistAddition,
Therapists.TherapistLastLoginDate
CAST(CASE WHEN Subscriptions.SubscriptionCount>0 then 1 else 0 end as BIT) as HasActiveSubscription,
Subscriptions.LastValidSubscriptionEnd
CAST(Subscriptions.IsPayingCustomer AS BIT) AS IsPayingCustomer,
COALESCE(ActiveSubscriptionMonthlyPrice,0) as ActiveSubscriptionMonthlyPrice
ClientStatus AS Status, Phone1 AS Phone, Phone2 AS Phone2,
ClientPayments.DiscountCouponCode,
DiscountCoupons.IssuedTo AS DiscountCouponIssuedTo,
DiscountCoupons.ClientDiscount AS DiscountCouponClientDiscount,
COALESCE(ClientFiles.TotalFilesCount,0) AS TotalFilesCount,
COALESCE(ClientFiles.TotalFilesSize,0) AS TotalFilesSize,
CAST((CASE WHEN C.CrmEnded = 1 THEN 1 ELSE 0 END) AS BIT) AS CrmEnded,
CrmStatus, CrmUnuseReason,
Crm_Calls.CrmCallCount
FROM dbo.Clients AS C
left join (
select A.UserName,
max(T.FirstName + ' ' + T.LastName) as FullName,
max(A.Email) as Email
from dbo.ApplicationUsers A
join dbo.Therapists T on T.ApplicationUserId=A.Id
group by A.Username
) ApplicationByName on ApplicationByName.UserName=C.ClientName
join dbo.Cities on Cities.ID=c.CityID
left join (
SELECT ClientId,
COUNT(*) AS TotalPatientCount,
sum(case when IsDeleted = 0 AND IsDisabled = 0 then 1 else 0 end) AS ActivePatientCount,
MAX(CreatedWhen) AS LastPatientAddition
FROM dbo.Patients
GROUP BY ClientId
) Patients on Patients.ClientId = C.Id
left join (
SELECT ClientId,
COUNT(*) AS TotalTreatmentCount,
MAX(CreatedWhen) AS LastTreatmentAddition
FROM dbo.Treatments
GROUP BY ClientId
) Treatments on Treatments.ClientID = C.Id
left join (
select T.ClientId,
count(distinct T.Id) as TotalTherapistCount,
sum(case when A.IsDeleted = 0 AND A.IsDisabled = 0 then 1 else 0 end) as ActiveTherapistCount,
max(A.CreatedWhen) as LastTherapistAddition,
max(A.LastLoginDate) as TherapistLastLoginDate
from Therapists T
left join dbo.ApplicationUsers A on A.Id=T.ApplicationUserId
group by T.ClientId
) Therapists on Therapists.ClientID = C.Id
left join (
SELECT S.ClientId,
count(*) as SubscriptionCount,
MAX(SubscriptionEnd) as LastValidSubscriptionEnd,
MAX(case when MinSub.Id!=S.ID then 1 else 0 end as IsPayingCustomer,
max(case when MonthlyPrice>0 then 0 end) as ActiveSubscriptionMonthlyPrice
FROM dbo.ClientSubscriptions S
join (
select ClientId, min(Id) as Id
from dbo.ClientSubscriptions
where IsDeleted=0
group by ClientId
) MinSub on MinSub.ClientId=ClientSubscriptions.ClientId
where IsDeleted=0 and (SubscriptionEnd is null or SubscriptionEnd>getdate())
group by ClientId
) Subscriptions on Subscriptions.ClientId=C.Id
left join (
select ClientId,
DiscountCouponCode,
row_number() over(partition by ClientId, order by Id) rn
from dbo.ClientPayments
) ClientPayments on ClientPayments.ClientId=C.ID and rn=1
left join dbo.DiscountCoupons on DiscountCoupons.Code=ClientPayments.DiscountCouponCode
left join (
select ClientId,
count(*) as TotalFilesCount,
sum(FileSize)/1048576.0 as TotalFilesSize
from dbo.ClientFiles
group by ClientId
) ClientFiles on ClientFiles.ClientId=Client.Id
left join (
SELECT Cust_id, COUNT(1) AS CrmCallCount
FROM dbo.Tipulog_Crm_Calls_new
group by Cust_id
) Crm_Calls on Crm_Calls.Cust_id=C.Id
WHERE C.IsDeleted = 0
This is a very partial answer, but you asked how to refer to a table once instead of multiple times in multiple subqueries.
This is an example of how you would replace all those subqueries to the Patients & Treatments tables, and also the cities table. You really need to learn about joins.
FROM dbo.Clients AS C
join dbo.Cities on Cities.ID=c.CityID
left join (
SELECT ClientId,
COUNT(*) AS TotalPatientCount,
sum(case when IsDeleted = 0 AND IsDisabled = 0 then 1 else 0 end) AS ActivePatientCount,
MAX(CreatedWhen) AS LastPatientAddition
FROM dbo.Patients
GROUP BY ClientId
) Patients on Patients.ClientId = C.Id
left join (
SELECT ClientId,
COUNT(*) AS TotalTreatmentCount,
MAX(CreatedWhen) AS LastTreatmentAddition
FROM dbo.Treatments
GROUP BY ClientId
) Treatments on Treatments.ClientID = C.Id
Then your column list replaces the subqueries to Patients and City like this:
Cities.Name AS City,
Patients.TotalPatientCount,
Patients.ActivePatientCount,
Patients.LastPatientAddition,
Treatments.TotalTreatmentCount,
Treatments.LastTreatmentAddition,
That should at least give you an idea.

SQL Select top parentId on a list of Id's and return row if all same top parentId

I have to script i would like to combine in to one:
SELECT [CategoryId] FROM [dbo].[Unit] where Id in (716,724)
and
DECLARE #Id INT = 15
;WITH cteGetRootID
As
(
SELECT
Id, [Name], ParentId, 1 AS CodePosition
FROM
Category WHERE Id = #Id
UNION All
SELECT
ic.Id, ic.[Name], ic.ParentId, CodePosition + 1
FROM Category ic
INNER JOIN cteGetRootID cte ON ic.Id = cte.ParentId
)
SELECT top 1 Id, [Name] FROM cteGetRootID
ORDER BY CodePosition desc
I would like to do low code for all result in first part and return Root Catogry if all have same Root
Like DECLARE #Id INT = SELECT [CategoryId] FROM [dbo].[Unit] where Id in (716,724)
Hope it make sence
You can use a join between dbo.Unit and dbo.Category in your first select of the union:
;WITH cteGetRootID
As
(
SELECT
c.Id, c.[Name], c.ParentId, 1 AS CodePosition
FROM
Category c
INNER JOIN [dbo].[Unit] u on u.CategoryID = c.Id
WHERE u.Id in (716,724)
UNION All
SELECT
ic.Id, ic.[Name], ic.ParentId, CodePosition + 1
FROM Category ic
INNER JOIN cteGetRootID cte ON ic.Id = cte.ParentId
)
SELECT top 1 Id, [Name] FROM cteGetRootID
ORDER BY CodePosition desc

Increment id value in SQL Server

In my SQL I have this query and I want to increase id with this insert that have
I don't want to use identity(1,1)
INSERT INTO dbo.tbl_waredetails
(wd_id, wd_mt_code, wd_wa_Id, wd_supply, wd_description, wd_status)
SELECT
(SELECT ISNULL(MAX(wd.wd_id), 0) + 1
FROM dbo.tbl_waredetails AS wd),
dbo.tbl_material.mat_code, #id,
dbo.fun_CompRem(mat_code, -1, #user_id) AS supply,
NULL, 0
FROM
tbl_material
INNER JOIN
dbo.tbl_MatUnit ON dbo.tbl_material.mat_MatUnt_Code = dbo.tbl_MatUnit.Matunt_code
INNER JOIN
dbo.tbl_MatGroup ON dbo.tbl_material.mat_MatGrp_Code = dbo.tbl_MatGroup.MatGrp_Code
but it send always 2 as id
Try below query
INSERT INTO dbo.tbl_waredetails
(wd_id, wd_mt_code, wd_wa_Id, wd_supply, wd_description, wd_status)
SELECT
(SELECT ISNULL(MAX(wd.wd_id), 0)
FROM dbo.tbl_waredetails AS wd)+ (row_number() over (order by wd.wd_id)),
dbo.tbl_material.mat_code, #id,
dbo.fun_CompRem(mat_code, -1, #user_id) AS supply,
NULL, 0
FROM
tbl_material
INNER JOIN
dbo.tbl_MatUnit ON dbo.tbl_material.mat_MatUnt_Code = dbo.tbl_MatUnit.Matunt_code
INNER JOIN
dbo.tbl_MatGroup ON dbo.tbl_material.mat_MatGrp_Code = dbo.tbl_MatGroup.MatGrp_Code
with cte as
(select (SELECT isnull(MAX(wd.wd_id),0) FROM dbo.tbl_waredetails ) as iden,dbo.tbl_material.mat_code,#id,
dbo.fun_CompRem(mat_code,-1,#user_id
)as supply,NULL,0
FROM tbl_material INNER JOIN
dbo.tbl_MatUnit ON dbo.tbl_material.mat_MatUnt_Code = dbo.tbl_MatUnit.Matunt_code INNER JOIN
dbo.tbl_MatGroup ON dbo.tbl_material.mat_MatGrp_Code = dbo.tbl_MatGroup.MatGrp_Code
where ROW_NUMBER ( )
OVER ( order by 1 )=1
union all
select c.iden+1,dbo.tbl_material.mat_code,#id,
dbo.fun_CompRem(mat_code,-1,#user_id
)as supply,NULL,0
FROM tbl_material INNER JOIN
dbo.tbl_MatUnit ON dbo.tbl_material.mat_MatUnt_Code = dbo.tbl_MatUnit.Matunt_code INNER JOIN
dbo.tbl_MatGroup ON dbo.tbl_material.mat_MatGrp_Code = dbo.tbl_MatGroup.MatGrp_Code
join cte as d on 1=1
where ROW_NUMBER ( )
OVER ( order by 1 )!=1
)
INSERT INTO dbo.tbl_waredetails
(
wd_id,
wd_mt_code ,
wd_wa_Id ,
wd_supply ,
wd_description ,
wd_status
)
SELECT iden, dbo.tbl_material.mat_code,#id,supply,NULL,0
FROM CTE

Ordering the results of CTE in SQL

I have following SQL:
;WITH CTE
AS (SELECT AL.*,
RV.FORENAME,
RV.SURNAME,
RV.USERNAME AS RegistrantUsername,
E.FORENAME AS EmployeeForename,
E.SURNAME AS EmployeeSurname,
U.USERNAME,
CASE
WHEN #Language = 2 THEN C.NAMELANG2
ELSE C.NAMELANG1
END AS CompanyName,
CASE
WHEN VC.COMPANYID IS NULL THEN
CASE
WHEN #Language = 2 THEN V.COMPANYNAMELANG2
ELSE V.COMPANYNAMELANG1
END
ELSE
CASE
WHEN #Language = 2 THEN VC.NAMELANG2
ELSE VC.NAMELANG1
END
END AS VacancyCompanyName,
CASE
WHEN #Language = 2 THEN V.JOBTITLELANG2
ELSE V.JOBTITLELANG1
END AS JobTitle,
ROW_NUMBER()
OVER(
PARTITION BY AL.REGISTRANTID, AL.COMPANYID
ORDER BY ACTIONDATE ASC) AS RN
FROM DBO.HR_ACTIONLOG AL
LEFT OUTER JOIN DBO.REGISTRANTSLISTVIEW RV
ON AL.REGISTRANTID = RV.REGISTRANTID
LEFT OUTER JOIN DBO.HR_EMPLOYEES E
ON AL.EMPLOYEEID = E.EMPLOYEEID
LEFT OUTER JOIN DBO.HR_USERS U
ON AL.USERID = U.USERID
LEFT OUTER JOIN DBO.HR_COMPANIES C
ON AL.COMPANYID = C.COMPANYID
LEFT OUTER JOIN DBO.HR_VACANCIES V
ON AL.VACANCYID = V.VACANCYID
LEFT OUTER JOIN DBO.HR_COMPANIES VC
ON V.COMPANYID = VC.COMPANYID
WHERE ( #Action IS NULL
OR AL.ACTION = #Action )
AND ( #DateFrom IS NULL
OR DBO.DATEONLY(AL.ACTIONDATE) >=
DBO.DATEONLY(#DateFrom) )
AND ( #DateTo IS NULL
OR DBO.DATEONLY(AL.ACTIONDATE) <= DBO.DATEONLY(#DateTo) )
AND ( #CompanyID IS NULL
OR AL.COMPANYID = #CompanyID )
AND ( #RegistrantID IS NULL
OR AL.REGISTRANTID = #RegistrantID )
AND ( #VacancyID IS NULL
OR AL.VACANCYID = #VacancyID )
--ORDER BY AL.ActionDate DESC
)
SELECT *
FROM CTE
WHERE RN = 1;
It returns first element from the group based on actiondate which is fine but the returned result is not ordered by date means returns each groups first record but the this collection of first records is not ordered by action date. I tried ORDER BY AL.ActionDate DESC in CTE but it gives error:
The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP or FOR XML is also specified.
Try this one -
;WITH CTE AS
(
SELECT ...
FROM dbo.hr_ActionLog AL
LEFT JOIN ...
WHERE AL.[Action] = ISNULL(#Action, AL.[Action])
AND dbo.DateOnly(AL.ActionDate) BETWEEN
dbo.DateOnly(ISNULL(#DateFrom, AL.ActionDate))
AND
dbo.DateOnly(ISNULL(#DateTo, '30000101'))
AND AL.CompanyID = ISNULL(#CompanyID, AL.CompanyID)
AND AL.RegistrantID = ISNULL(#RegistrantID, AL.RegistrantID)
AND AL.VacancyID = ISNULL(#VacancyID, AL.VacancyID)
)
SELECT *
FROM CTE
WHERE RN = 1
ORDER BY AL.ActionDate DESC;
Move order by clause outside of cte:
WITH CTE AS
(
...
)
SELECT *
FROM CTE
WHERE RN = 1;
ORDER BY ActionDate DESC
you do the ordering outside CTE
WITH CTE
AS
{
....
}
SELECT *
FROM CTE
WHERE RN = 1
ORDER BY ActionDate DESC
Yes, the only ORDER BY that affects the order in which the results are returned is one placed on the outermost SELECT:
SELECT *
FROM CTE
WHERE RN = 1
ORDER BY ActionDate DESC
You have a ROW_NUMBER function inside the CTE and the query only takes the row with RN=1.
If I understand the problem correctly, just change the ORDER BY clause in the ROW_NUMBER function and you should get the results you're looking for.