How to retrieve rows multiple times in SQL Server? - sql

These are my rows that I initially retrieved:
112 Cem Ceminay
210 Ali Salih
132 Gül Sen
Now I want to clone every row to be duplicated as 3 rows. So the new results:
112 Cem Ceminay
112 Cem Ceminay
112 Cem Ceminay
210 Ali Salih
210 Ali Salih
210 Ali Salih
132 Gül Sen
132 Gül Sen
132 Gül Sen
What kind of select statement can help me?
Example select statement:
SELECT id,name,surname FROM people;
Thank you lovely people...
PS: My query:
SELECT
Faturalar.faturaNo
,Klinikler.SAPSirketKodu [COMPANY CODE]
,Klinikler.SAPBussinessArea [BUSINESS AREA]
,BasilmisFaturalar.basilmisFatura_id [REFERENCE]
,BasilmisFaturalar.duzenlemeTarihi [DOCUMENT DATE]
,BasilmisFaturalar.duzenlemeTarihi [BASELINE DATE]
,Kurumlar.sapKodu [ACCOUNT]
,Kurumlar.kurumAdi + ' adına '+Faturalar.faturaNo+' nolu fatura' [TEXT]
,BasilmisFaturalar.kdvDahilToplamTutar [AMOUNT]
,BasilmisFaturalar.kdvHaricToplamTutar
,(BasilmisFaturalar.kdvDahilToplamTutar-BasilmisFaturalar.kdvHaricToplamTutar) AS kdvTutari
,CASE
WHEN BasilmisFaturalar.kdvOrani = 0 THEN 'A0'
WHEN BasilmisFaturalar.kdvOrani = 8 THEN '2H'
WHEN BasilmisFaturalar.kdvOrani = 18 THEN '3H'
END [TAX CODE]
,Klinikler.profitCenter [COST CENTER/PROFIT CENTER]
FROM Faturalar
-- Fatura yazdırılmış olmalı
INNER JOIN BasilmisFaturalar ON BasilmisFaturalar.basilmisFatura_id = Faturalar.refBasilmisFatura_id
-- Yazdırılmış fatura iptal edilmemiş olmalı
INNER JOIN BasiliFaturaIptalTalepleri ON BasiliFaturaIptalTalepleri.refBasilmisFatura_id <> BasilmisFaturalar.basilmisFatura_id
-- Fatura Kurum Detaylarından KURUM bilgilerine
INNER JOIN KurumFaturaDetaylari ON KurumFaturaDetaylari.kurumFaturaDetay_id = BasilmisFaturalar.refKurumFaturaDetay_id
-- Faturanın kesildiği kurum
INNER JOIN Kurumlar ON Kurumlar.kurum_id = dbo.KurumFaturaDetaylari.refKurum_id
-- Seanslar üzerinden Klinik bilgilerine böylece SAPcc, SAPba, ProfitCenter a ulaşıyoruz
INNER JOIN Seanslar ON Seanslar.refFatura_id = Faturalar.fatura_id
INNER JOIN dbo.Klinikler ON dbo.Klinikler.klinik_id = Seanslar.refKlinik_id
-- Belirli bir düzenleme tarihi aralığında olmalı
WHERE BasilmisFaturalar.duzenlemeTarihi BETWEEN DATEADD(m,-1,GETDATE()) AND GETDATE()
GROUP BY Faturalar.faturaNo,BasilmisFaturalar.basilmisFatura_id,kdvDahilToplamTutar
,kdvHaricToplamTutar
,BasilmisFaturalar.kdvOrani
,BasilmisFaturalar.duzenlemeTarihi
,Kurumlar.sapKodu
,Klinikler.SAPBussinessArea
,Klinikler.SAPSirketKodu
,Klinikler.profitCenter
,Kurumlar.kurumAdi

To help explain: Cartesian product/cross join background
SELECT
people.id, people.name, people.surname
FROM
people
CROSS JOIN
(SELECT 1 AS foo UNION ALL SELECT 2 UNION ALL SELECT 3) bar;
After comment elsewhere about 7 tables and 42 lines
SELECT
Singles.*
FROM
(
SELECT
Faturalar.faturaNo
,Klinikler.SAPSirketKodu [COMPANY CODE]
,Klinikler.SAPBussinessArea [BUSINESS AREA]
,BasilmisFaturalar.basilmisFatura_id [REFERENCE]
,BasilmisFaturalar.duzenlemeTarihi [DOCUMENT DATE]
,BasilmisFaturalar.duzenlemeTarihi [BASELINE DATE]
,Kurumlar.sapKodu [ACCOUNT]
,Kurumlar.kurumAdi + ' adına '+Faturalar.faturaNo+' nolu fatura' [TEXT]
,BasilmisFaturalar.kdvDahilToplamTutar [AMOUNT]
,BasilmisFaturalar.kdvHaricToplamTutar
,(BasilmisFaturalar.kdvDahilToplamTutar-BasilmisFaturalar.kdvHaricToplamTutar) AS kdvTutari
,CASE
WHEN BasilmisFaturalar.kdvOrani = 0 THEN 'A0'
WHEN BasilmisFaturalar.kdvOrani = 8 THEN '2H'
WHEN BasilmisFaturalar.kdvOrani = 18 THEN '3H'
END [TAX CODE]
,Klinikler.profitCenter [COST CENTER/PROFIT CENTER]
FROM Faturalar
-- Fatura yazdırılmış olmalı
INNER JOIN BasilmisFaturalar ON BasilmisFaturalar.basilmisFatura_id = Faturalar.refBasilmisFatura_id
-- Yazdırılmış fatura iptal edilmemiş olmalı
INNER JOIN BasiliFaturaIptalTalepleri ON BasiliFaturaIptalTalepleri.refBasilmisFatura_id <> BasilmisFaturalar.basilmisFatura_id
-- Fatura Kurum Detaylarından KURUM bilgilerine
INNER JOIN KurumFaturaDetaylari ON KurumFaturaDetaylari.kurumFaturaDetay_id = BasilmisFaturalar.refKurumFaturaDetay_id
-- Faturanın kesildiği kurum
INNER JOIN Kurumlar ON Kurumlar.kurum_id = dbo.KurumFaturaDetaylari.refKurum_id
-- Seanslar üzerinden Klinik bilgilerine böylece SAPcc, SAPba, ProfitCenter a ulaşıyoruz
INNER JOIN Seanslar ON Seanslar.refFatura_id = Faturalar.fatura_id
INNER JOIN dbo.Klinikler ON dbo.Klinikler.klinik_id = Seanslar.refKlinik_id
-- Belirli bir düzenleme tarihi aralığında olmalı
WHERE BasilmisFaturalar.duzenlemeTarihi BETWEEN DATEADD(m,-1,GETDATE()) AND GETDATE()
GROUP BY Faturalar.faturaNo,BasilmisFaturalar.basilmisFatura_id,kdvDahilToplamTutar
,kdvHaricToplamTutar
,BasilmisFaturalar.kdvOrani
,BasilmisFaturalar.duzenlemeTarihi
,Kurumlar.sapKodu
,Klinikler.SAPBussinessArea
,Klinikler.SAPSirketKodu
,Klinikler.profitCenter
,Kurumlar.kurumAdi
) Singles
CROSS JOIN
(SELECT 1 AS foo UNION ALL SELECT 2 UNION ALL SELECT 3) Multiplier;

How about:
SELECT id,name,surname FROM people
UNION ALL
SELECT id,name,surname FROM people
UNION ALL
SELECT id,name,surname FROM people
and possibly add a
ORDER BY id, name
to it if you want it ordered.
Marc

Related

Multiplying 2 columns in sql but calculation is incorrect?

I have the following select statement:
SELECT c.compname AS [Company]
,e.empname AS [Employee Name]
,a.jobid AS [Job Number]
,a.JobNavn AS [Job Name]
,t.TName [Task Name]
,cu.DayDate AS [Booking Date]
,cu.HrsBooked AS [Scheduled Hours]
,x.Ressnavn AS [Client]
,tr.Sale
,SUM(cu.HrsBooked) * (tr.Sale) AS [Total]
FROM job a
INNER JOIN jobplan jp ON jp.JobId = a.jobid
INNER JOIN JobDimensions AS z ON z.jobid = a.jobid
INNER JOIN Ress AS x ON x.RessId = z.custid
INNER JOIN JobPrice AS y ON y.JobId = a.Jobid
INNER JOIN task t ON t.PlanId = jp.PlanId
INNER JOIN JobPriceactivity AS w ON w.priceId = y.priceId
INNER JOIN taskres tr ON tr.TaskId = t.TaskId
INNER JOIN emp e ON e.EmpId = tr.ResId
INNER JOIN comp c ON e.compid = c.compid
INNER JOIN CapUsed AS cu ON cu.RefId = tr.TaskResId
AND cu.RefType = 1
INNER JOIN arpaccount AS ar ON e.empname = ar.arpaccname
AND CAST(cu.DayDate AS DATE) BETWEEN #startdate
AND #enddate
WHERE e.EMPID >= '2'
AND cu.HrsBooked > '0'
GROUP BY c.compname
,e.empname
,a.jobid
,a.JobNavn
,t.TName
,cu.DayDate
,cu.HrsBooked
,x.Ressnavn
,y.priceid
,tr.Sale
But the calculation of my 'SUM' in the select is not correct as highlighted in yellow in the following extract
I was expecting something like the below highlighted in green:
Can anyone highlight where I am going wrong either in my main code or column sum?

Unexplainable SQL behaviour

I have a simple SQL query, with a handful of joined queries.
In my select I have a function shaping the date to a string format as below
LEFT(REPLACE(ADM_DT,'-',''),8)+REPLACE(ADM_TM,':','')+'00'
The script I am running should return 84 rows currently, but when executing the above in the select, it continuosly returns a different volume of rows every execution? there are no changes to the underlying tables between executions.
The strange thing is that whe I swith this back to a standard date conversion, the rows total 84
CONVERT(DATETIME,CONVERT(NVARCHAR,ADM_DT)+' '+ADM_TM)
Can anyone explain why SQL is behaving this way, I have not seen this before?
Full script below:
SELECT
[Visit ID] = a050.HSP_NO
,[Current Site] = currwd.HOSP
,[Current Specialty] = curr.SPEC
,[Current Ward] = currwd.WARD
,[Current Ward Name] = REPLACE(currwd.CURRDESC,'"','')
,[Current Consultant] = curr.PROF
,[Admission Date] = LEFT(REPLACE(ADM_DT,'-',''),8)+REPLACE(ADM_TM,':','')+'00'
,[Active] = '1'
,[PAS ID] = [crn].[crn]
,[Patient Class] = 'IP'
,NHS.[nhsno]
,CHI.CHI
,CASE WHEN OSV.X_CN IS NOT NULL THEN 'OSV' ELSE '' END OSV
,CASE WHEN NHS.[nhsno] LIKE '7%' THEN '7 NHSNO' ELSE '' END [PROBLEM NHS NO]
,DATEDIFF(D,PATS.DATE_OF_BIRTH,CONVERT(DATE,ADM_DT)) /365 [AGE ON ADMISSION]
FROM PCSSSA..SILVER.APK050_HPROVSPELL a050 WITH (NOLOCK)
-- Current Admission details
LEFT JOIN (
SELECT X_CN, CEP_NO, HSP_NO, SPEC, PROF --MSPEC
FROM PCSSSA..SILVER.APK051_CONEPIS epi WITH (NOLOCK)
-- Main Specialty Map
LEFT JOIN PCSSSA..SILVER.ENV050_DISCIPDETS en050 WITH (NOLOCK)
ON epi.SPEC = en050.OBJ_DISC
AND en050.OBJ_TYPE='SP'
AND en050.DATE_TO IS NULL
)curr
ON curr.X_CN = a050.X_CN
AND a050.HSP_NO = curr.HSP_NO
AND curr.CEP_NO = (SELECT TOP 1 a051.CEP_NO
FROM PCSSSA..SILVER.APK051_CONEPIS a051 WITH (NOLOCK)
Where a051.X_CN = a050.X_CN AND a050.HSP_NO = a051.HSP_NO
Order By CEP_NO DESC)
-- Current Ward Detail
JOIN (SELECT *, ROW_NUMBER() OVER (PARTITION BY X_CN, CEP_NO ORDER BY WS_NO DESC) AS WR
FROM PCSSSA..SILVER.APK052_WARDSTAY wdstay WITH (NOLOCK)
LEFT JOIN (SELECT
CURRWARD = OBJ_LOC,
CURRDESC = OBJ_DESC
FROM [PCSSSA]..[SILVER].[ENV030_LOCDETS] WITH (NOLOCK)
WHERE OBJ_TYPE = 'WARD'
AND DATE_TO IS NULL
)wdname
ON wdstay.WARD = wdname.CURRWARD
) currwd
ON curr.X_CN = currwd.X_CN
AND curr.CEP_NO = currwd.CEP_NO
AND currwd.WR=1
--- Admitting details
LEFT JOIN (
SELECT X_CN, CEP_NO, HSP_NO, PROF, SPEC --MSPEC
FROM PCSSSA..SILVER.APK051_CONEPIS epi WITH (NOLOCK)
-- Main Specialty Map
LEFT JOIN PCSSSA..SILVER.ENV050_DISCIPDETS en050 WITH (NOLOCK)
ON epi.SPEC = en050.OBJ_DISC
AND en050.OBJ_TYPE='SP'
AND en050.DATE_TO IS NULL
)adm
ON adm.X_CN = a050.X_CN AND a050.HSP_NO = adm.HSP_NO
AND adm.CEP_NO = (SELECT TOP 1 a051.CEP_NO
FROM PCSSSA..SILVER.APK051_CONEPIS a051 WITH (NOLOCK)
Where a051.X_CN = a050.X_CN AND a050.HSP_NO = a051.HSP_NO
Order By CEP_NO)
-- Admitting Ward Detail
JOIN (SELECT *, ROW_NUMBER() OVER (PARTITION BY X_CN,CEP_NO ORDER BY WS_NO) AS WR FROM PCSSSA..SILVER.APK052_WARDSTAY WITH (NOLOCK)) admwd
ON adm.X_CN = admwd.X_CN
AND adm.CEP_NO = admwd.CEP_NO
AND admwd.WR=1
-- Patient Detail
LEFT JOIN
(SELECT
[id].[RM_PATIENT_NO],
[id].[NUM_ID_TYPE] + CONVERT(NVARCHAR,[NUMBER_ID]) [crn]
FROM [PCSSSA]..[SILVER].[NUMBER_IDS] [id] WITH (NOLOCK)
WHERE [id].[NUM_ID_TYPE] IN ('0', '1', 'W')
)[crn]
ON a050.[X_CN] = [crn].[RM_PATIENT_NO]
-- NHS NUMBERS
LEFT JOIN
(
SELECT
[id].[RM_PATIENT_NO],
[id].[NUMBER_ID] [nhsno]
FROM [PCSSSA]..[SILVER].[NUMBER_IDS] [id] WITH (NOLOCK)
WHERE [id].[NUM_ID_TYPE] = ('NHS')
)NHS
ON NHS.RM_PATIENT_NO = a050.X_CN
-- CHI NUMBER
LEFT JOIN
(
SELECT
[id].[RM_PATIENT_NO],
[id].[NUMBER_ID] [CHI]
FROM [PCSSSA]..[SILVER].[NUMBER_IDS] [id] WITH (NOLOCK)
WHERE [id].[NUM_ID_TYPE] IN ('CHI')
)CHI
ON CHI.RM_PATIENT_NO = a050.X_CN
-- OVERSEES STATUS
LEFT JOIN
(
SELECT X_CN, [STATUS], SDATE, EDATE FROM PCSSSA..SILVER.CRS037_OSV_STATUS WITH (NOLOCK)
)OSV
ON OSV.X_CN = a050.X_CN
AND CONVERT(DATE,ADM_DT) >= OSV.SDATE
AND (OSV.SDATE IS NULL
OR CONVERT(DATE,ADM_DT) <= OSV.EDATE)
-- DEMOGRAPHICS
LEFT JOIN
(
SELECT RM_PATIENT_NO, DATE_OF_BIRTH FROM PCSSSA..[SILVER].[PATIENTS] WITH (NOLOCK)
)PATS
ON PATS.RM_PATIENT_NO = a050.X_CN
-- CURRENTLY ADMITTED ONLY
WHERE DIS_DT IS NULL
-- WITHOUT NHS NUMBER
AND (nhsno IS NULL
-- OR BRING IN ANY 7 NHS NUMBERS FOR CORRECTION
OR NHS.[nhsno] LIKE '7%'
-- ALSO INCLUDE OVERSEES
OR OSV.X_CN IS NOT NULL)
What is even stranger, is that if you wrap this in a subquery and coun(*) on the outer then it totals 84 as expected, very strange!

SQL Server - Display two different dates on two different lines

I'm currently struggling to get my query to display two dates on two lines. i.e. I have two lines, with two columns for two dates. I need one line to have null then date, the second line to have date then null. Example shown in image below - only one of these dates needs to show up per line.
Two lines two dates
Google has not been my friend thus far because it's a rather obscure thing to try and describe to the search engine. Any help would be greatly appreciated. Full query is below:
WITH CTE AS
(
SELECT *,
ROW_NUMBER() OVER(PARTITION BY person_code ORDER BY unit_instance_code) AS rn
FROM learner_aims
)
SELECT DISTINCT p.person_code [ID],
p.forename [Forename],
p.surname [Surname],
uio.long_description [CourseDesc],
CASE rn
WHEN 1 THEN NULL
WHEN 2 THEN CONVERT(DATE, sub.[GIL Start Date], 103)
END AS [GIL Start Date],
CASE rn
WHEN 1 THEN CONVERT(DATE, sub.[Non-GIL Start Date], 103)
WHEN 2 THEN NULL
END AS [Non-GIL Start Date]
-- CONVERT(DATE, sub.[GIL Start Date], 103) [GIL Start Date],
-- CONVERT(DATE, sub.[Non-GIL Start Date], 103) [Non-GIL Start Date]
FROM people p
INNER JOIN learner_aims la ON p.person_code = la.person_code
INNER JOIN unit_instance_occurrences uio ON uio.uio_id = la.uio_id
INNER JOIN cte ON cte.person_code = p.person_code
LEFT JOIN (SELECT DISTINCT p.person_code [ID],
p.forename [Forename],
p.surname [Surname],
MIN(fy22.earlieststartdate) [GIL Start Date],
MIN(fy22sub.earlieststartdate) [Non-GIL Start Date]
FROM people p
INNER JOIN learner_aims la ON p.person_code = la.person_code
INNER JOIN unit_instance_occurrences uio ON uio.uio_id = la.uio_id
LEFT OUTER JOIN (
SELECT p.person_code [ID],
p.forename [Forename],
p.surname [Surname],
uio.course_occurrence_code [CourseCode],
uio.long_description [CourseDesc],
uio.owning_organisation [OwningOrg],
uio.offering_organisation [OfferingOrg],
la.uio_id [uio_id],
MIN(CONVERT(DATE, la.start_date, 103)) [EarliestStartDate]
FROM people p
INNER JOIN learner_aims la ON p.person_code = la.person_code
INNER JOIN unit_instance_occurrences uio ON uio.uio_id = la.uio_id
WHERE la.ilr = 'Y'
AND la.funding_year = '22'
AND (
uio.course_occurrence_code LIKE 'GIL%'
OR uio.course_occurrence_code LIKE 'SEED%'
)
GROUP BY p.person_code,
p.forename,
p.surname,
uio.course_occurrence_code,
uio.long_description,
uio.owning_organisation,
uio.offering_organisation,
la.uio_id
) [FY22] ON fy22.id = la.person_code
LEFT OUTER JOIN (
SELECT p.person_code [ID],
p.forename [Forename],
p.surname [Surname],
uio.course_occurrence_code [CourseCode],
uio.long_description [CourseDesc],
uio.owning_organisation [OwningOrg],
uio.offering_organisation [OfferingOrg],
la.uio_id [uio_id],
MIN(CONVERT(DATE, la.start_date, 103)) [EarliestStartDate]
FROM people p
INNER JOIN learner_aims la ON p.person_code = la.person_code
INNER JOIN unit_instance_occurrences uio ON uio.uio_id = la.uio_id
WHERE la.ilr = 'Y'
AND la.funding_year = '22'
AND uio.course_occurrence_code NOT LIKE 'GIL%'
AND uio.course_occurrence_code NOT LIKE 'SEED%'
AND la.person_code IN (
SELECT la.person_code [ID]
FROM people p
INNER JOIN learner_aims la ON p.person_code = la.person_code
INNER JOIN unit_instance_occurrences uio ON uio.uio_id = la.uio_id
WHERE la.ilr = 'Y'
AND la.funding_year = '22'
AND (
uio.course_occurrence_code LIKE 'GIL%'
OR uio.course_occurrence_code LIKE 'SEED%'
)
)
GROUP BY p.person_code,
p.forename,
p.surname,
uio.course_occurrence_code,
uio.long_description,
uio.owning_organisation,
uio.offering_organisation,
la.uio_id
) [FY22SUB] ON fy22sub.id = la.person_code
WHERE la.funding_year = '22' AND la.ilr = 'Y'
GROUP BY p.person_code,
p.forename,
p.surname
HAVING MIN(CONVERT(DATE, fy22sub.earlieststartdate, 103)) > MIN(CONVERT(DATE, fy22.earlieststartdate, 103))
) sub ON sub.id = la.person_code
WHERE la.funding_year = '22' AND la.ilr = 'Y'
ORDER BY 3, 2
That's not clear what determines if the row is first or second, I did it in base of the text in the second column as it's the only thing that changes.
So the idea here is to enumerate the rows (order by 2) and then to show the date as you want:
declare #t table (id int, CourseDesc varchar(100), [GIL Start Date] date, [Non-GIL Start Date] date);
insert into #t values(21571, 'text1', '20151116', '20160222'), (21571, 'text2', '20151116', '20160222');
with cte as
(
select *,
row_number() over(partition by id order by CourseDesc)as rn
from #t
)
select id, CourseDesc,
case rn
when 1 then null
when 2 then [GIL Start Date]
end as [GIL Start Date],
case rn
when 1 then [Non-GIL Start Date]
when 2 then null
end as [Non-GIL Start Date]
from cte;

Query takes too long if i include a column in select statement

Below is the query which i need to optimize:
DECLARE #Power VARCHAR(10), #Button VARCHAR(10), #Casing VARCHAR(10), #Screen VARCHAR(10)
SELECT #Power = ActivityId FROM t_Activity WHERE ActivityName = 'PhonePowersUp?'
SELECT #Button = ActivityId FROM t_Activity WHERE ActivityName = 'T/S and Buttons functioning OK?'
SELECT #Casing = ActivityId FROM t_Activity WHERE ActivityName = 'Casing - no major defects?'
SELECT #Screen = ActivityId FROM t_Activity WHERE ActivityName = 'LCD works OK?'
SELECT
HQ.HandsetQuoteId [HandsetQuoteId], SS.Name [quote_status], HQ.QuoteDate [Quote Date], INS.DateInspected [DateInspected], PA.IMEI [IMEI_Quoted],
PA1.IMEI [IMEI_Inspected], INS.Grade [Grade], PB.PackageBoxName [PackageBoxName], CC.Name [ContactChannel], PhnBrd.Name [Brand], PM.ModelName [ModelQuoted],
PM1.ModelName [ModelInspected], U.FirstName [FirstName], U.Surname [Surname], U.Username [Username], UW.WarehouseId [WarehouseId], W.Name [Warehouse Name],
HQA.Value [Original Quote Value], HQ.QuoteValue [Quote Value], INS.InspectionValue [InspectionValue], HQ.AgreedValue [Agreed Value], CUS.FirstName [Store Name],
DATEDIFF(DAY, HQ.QuoteDate, GETDATE()) [Quote Age],
[ST_POWER] = CASE WHEN (CHARINDEX(','+ #Power +',', ','+PAR.Ok+',') > 0) THEN 'YES' WHEN (CHARINDEX(','+ #Power +',', ','+PAR.Fault+',') > 0) THEN 'NO' ELSE NULL END,
[ST_BUTTONS] = CASE WHEN (CHARINDEX(','+ #Button +',', ','+PAR.Ok+',') > 0) THEN 'YES' WHEN (CHARINDEX(','+ #Button +',', ','+PAR.Fault+',') > 0) THEN 'NO' ELSE NULL END,
[ST_CASING] = CASE WHEN (CHARINDEX(','+ #Casing +',', ','+PAR.Ok+',') > 0) THEN 'YES' WHEN (CHARINDEX(','+ #Casing +',', ','+PAR.Fault+',') > 0) THEN 'NO' ELSE NULL END,
[ST_Screen] = CASE WHEN (CHARINDEX(','+ #Screen +',', ','+PAR.Ok+',') > 0) THEN 'YES' WHEN (CHARINDEX(','+ #Screen +',', ','+PAR.Fault+',') > 0) THEN 'NO' ELSE NULL END,
st_deduct = PAR.PercentageDeduction, wt_deduct = MAX(APD.PercentageDeduction)
FROM t_Inspection AS INS
INNER JOIN t_HandsetQuote HQ ON HQ.HandsetQuoteId = INS.HandsetQuoteId
INNER JOIN t_QuoteHeader QH ON QH.QuoteHeaderId = HQ.QuoteHeaderId
INNER JOIN t_Customer CUS ON CUS.CustomerId = QH.CustomerId
INNER JOIN t_ContactChannel CC ON CC.ContactChannelId = CUS.ContactChannelId
INNER JOIN t_PackageBoxHandset PBH ON PBH.HandsetQuoteId = HQ.HandsetQuoteId
INNER JOIN t_PackageBox PB ON PB.PackageBoxId = PBH.PackageBoxId
INNER JOIN t_StockStatus SS ON SS.StockStatusId = HQ.StockStatusId
INNER JOIN t_PhoneAudit PA ON PA.PhoneAuditId = HQ.QuotePhoneAuditId
INNER JOIN t_PhoneModel PM ON PM.PhoneModelId = PA.PhoneModelId AND PA.PhoneAuditId = HQ.QuotePhoneAuditId
INNER JOIN t_PhoneBrand PhnBrd ON PM.PhoneBrandId = PhnBrd.PhoneBrandId
INNER JOIN t_PhoneAudit PA1 ON PA1.PhoneAuditId = HQ.InspectionPhoneAuditId
INNER JOIN t_PhoneModel PM1 ON PM1.PhoneModelId = PA1.PhoneModelId AND PA1.PhoneAuditId = HQ.InspectionPhoneAuditId
INNER JOIN t_PhoneBrand PhnBrd1 ON PM1.PhoneBrandId = PhnBrd1.PhoneBrandId
INNER JOIN t_User U ON INS.InspectorId = U.UserId
INNER JOIN t_UserWarehouse UW ON U.UserId = UW.UserId
INNER JOIN t_Warehouse W ON UW.WarehouseId = W.WarehouseId
LEFT JOIN t_HandsetQuoteAdditionalInfo HQA ON HQ.HandsetQuoteId = HQA.HandsetQuoteId AND HQA.KeyName = 'OriginalQuoteValue'
LEFT JOIN t_PhoneAuditRetail PAR ON PAR.HandsetQuoteId = HQ.HandsetQuoteId
LEFT JOIN t_HandsetQuoteActivity HQA1 ON HQA1.HandsetQuoteId = HQ.HandsetQuoteId AND HQA1.ActivityTestOK = 0 AND HQA1.ActivityStartTime = (
CASE
WHEN ((SELECT Count(1) FROM t_HandsetQuoteActivity WHERE HandsetQuoteId = HQA1.HandsetQuoteId AND ActivityStartTime <= QH.Cache_QuoteAcceptedDate AND ActivityId = HQA1.ActivityId) > 0)
THEN (SELECT Max(ActivityStartTime) FROM t_HandsetQuoteActivity WHERE HandsetQuoteId = HQA1.HandsetQuoteId AND ActivityStartTime <= QH.Cache_QuoteAcceptedDate AND ActivityId = HQA1.ActivityId GROUP BY HandsetQuoteId, ActivityId)
ELSE
(SELECT Min(ActivityStartTime) FROM t_HandsetQuoteActivity WHERE HandsetQuoteId = HQA1.HandsetQuoteId AND ActivityStartTime >= QH.Cache_QuoteAcceptedDate AND ActivityId = HQA1.ActivityId GROUP BY HandsetQuoteId, ActivityId)
END)
LEFT JOIN t_Activity_PercentageDeduction APD ON APD.ActivityId = HQA1.ActivityId AND APD.ContactChannelId = CUS.ContactChannelId AND APD.ContactChannelId = CC.ContactChannelId
WHERE Ins.DateInspected > GETDATE()-90
GROUP BY HQ.HandsetQuoteId, SS.Name, QH.CreatedDate, INS.DateInspected, PA.IMEI, PA1.IMEI, INS.Grade, PB.PackageBoxName, CC.Name, PhnBrd.Name, PM.ModelName, PM1.ModelName,
U.FirstName, U.Surname, U.Username, UW.WarehouseId, W.Name, HQA.Value, HQ.QuoteValue, INS.InspectionValue, HQ.AgreedValue, CUS.Firstname, HQ.QuoteDate, PAR.Ok, PAR.Fault,
PAR.PercentageDeduction
And, after properly debugging it, I came to know that when i remove wt_deduct = MAX(APD.PercentageDeduction) from the select list, the query executes with in less than a minute.
But, however i am not able to figure it out, that whats wrong with the column APD.PercentageDeduction, because when i include it in the select list, my query stucks and becomes too slow and takes 15 minutes to run and excluding it from the select list makes the query to run with in 30 seconds.
Additional Information:
Table -> t_Activity_PercentageDeduction contains only 400 records, column PercentageDeduction is of Decimal datatype.
Please let me know if you want some other information too.
If Im not mistaken you are only joining to that table in order to get that MAX value, and by adding this Max value, you are also having to do all the grouping. So there is actually quite a difference in the queries.
I would suggest using a co-related sub-query to get this piece of data.
remove the left join
LEFT JOIN t_Activity_PercentageDeduction APD ON APD.ActivityId = HQA1.ActivityId AND APD.ContactChannelId = CUS.ContactChannelId AND APD.ContactChannelId = CC.ContactChannelId
and set wt_deduct = to the new co-related sub-query
wt_deduct = (select MAX(PercentageDeduction) from t_Activity_PercentageDeduction
where ActivityId = HQA1.ActivityId
AND ContactChannelId = CUS.ContactChannelId
AND ContactChannelId = CC.ContactChannelId)
And you can remove all the grouping that is no longer required too.

How to pick Max value of SQL Output

SQL Query Syntax issue. I have a query which returns around 150,000 rows of records. In this query, you can see ROW_NUMBER() OVER PARTITION. On select * from cte, I need to pick only the highest value of ROW_NUMBER() for each Pat_id.
If RowNumber is 150 for one pat_id. I need only that row of records. I am having difficult in narrowing down to one record. I request experts to share your syntax to help me.
with cte
as (
select pat.pat_id,
pat.fname as [FirstName],
pat.mname as [MiddleName],
pat.lname as [LastName],
[DOB] =Convert(VARCHAR(12),pat.birth_date,101),
csc.name as [AccountType],
[Plan Name] = CASE when (isnull(org.name,'')='') then 'CASH' else org.name end
,cprx_disp.disp_days_supply
,cprx_disp.dispense_date
,(cprx_disp.dispense_date + cprx_disp.disp_days_supply) as [DateDue]
,ROW_NUMBER() over(PARTITION BY pat.pat_id ORDER BY cprx_disp.dispense_date) as [RowNumber]
From cppat pat (nolock)
left outer join cppat_ins patins(NoLock) ON patins.pat_id = pat.pat_id
left outer join csorg org on org.org_id = patins.org_id
inner join csct_code csc on pat.pat_type_cn = csc.code_num
join cprx on cprx.pat_id = pat.pat_id
join cprx_disp (nolock) on cprx.last_rxdisp_id = cprx_disp.rxdisp_id
where csc.ct_id = 163
and csc.code_num in (1033,1010,1011,1012,1016,1017,1016,1018)
and patins.status_cn = 1
and patins.priority = 1
-- Commented.
-- and pat.pat_id = 2561
)
select cte.[FirstName],
cte.[MiddleName],
cte.[LastName],
cte.[DOB],
cte.[AccountType],
cte.[Plan Name],
Cte.DateDue
from cte
Well, you're not actually using the RowNumber in the output, so I would just reverse it and then return those that equal 1:
with cte
as (
select pat.pat_id,
pat.fname as [FirstName],
pat.mname as [MiddleName],
pat.lname as [LastName],
[DOB] =Convert(VARCHAR(12),pat.birth_date,101),
csc.name as [AccountType],
[Plan Name] = CASE when (isnull(org.name,'')='') then 'CASH' else org.name end
,cprx_disp.disp_days_supply
,cprx_disp.dispense_date
,(cprx_disp.dispense_date + cprx_disp.disp_days_supply) as [DateDue]
,ROW_NUMBER() over(PARTITION BY pat.pat_id ORDER BY cprx_disp.dispense_date DESC) as [RowNumber]
from cppat pat (nolock)
left outer join cppat_ins patins(NoLock) on patins.pat_id = pat.pat_id
left outer join csorg org on org.org_id = patins.org_id
inner join csct_code csc on pat.pat_type_cn = csc.code_num
join cprx on cprx.pat_id = pat.pat_id
join cprx_disp (nolock) on cprx.last_rxdisp_id = cprx_disp.rxdisp_id
where csc.ct_id = 163
and csc.code_num in (1033,1010,1011,1012,1016,1017,1016,1018)
and patins.status_cn = 1
and patins.priority = 1
-- Commented.
-- and pat.pat_id = 2561
)
select cte.[FirstName],
cte.[MiddleName],
cte.[LastName],
cte.[DOB],
cte.[AccountType],
cte.[Plan Name],
cte.DateDue
from cte
WHERE RowNumber = 1;