Related
I have 2 queries that I want to optimize but I don't know how. The execution time is not acceptable for me.
I'm working with jira database and did query to show different tasks with some attributes.
The code is:
SET NOCOUNT ON
DROP TABLE IF EXISTS #TT
DROP TABLE IF EXISTS #TT1
DROP TABLE IF EXISTS #TT2
SELECT DISTINCT concat(pr.[pkey], '-', ji.[issuenum]) AS 'Ключ'
,concat('https://sd.finam.ru/browse/', pr.[pkey], '-', ji.[issuenum]) AS 'Ссылка'
,p.[pname] AS 'П'
,users.[display_name] AS 'Исполнитель'
,CAST(ji.[CREATED] AS smalldatetime) AS 'Создан'
,CAST(ji.[RESOLUTIONDATE] AS smalldatetime) AS 'Дата резолюции'
,ji.[issuenum]
INTO #TT
FROM
[jiraissue] AS ji
LEFT OUTER JOIN [changegroup] AS cg ON (cg.[issueid] = ji.[id])
LEFT OUTER JOIN [changeitem] AS ci ON (ci.[groupid] = cg.[id]) AND ci.FIELDTYPE='jira' AND ci.FIELD='status'
LEFT OUTER JOIN [app_user] AS au ON (au.[user_key] = cg.[AUTHOR])
LEFT OUTER JOIN [issuetype] AS itype ON (itype.[ID] = ji.[issuetype])
LEFT OUTER JOIN [priority] AS p ON (p.[ID] = ji.[PRIORITY])
LEFT OUTER JOIN [project] AS pr ON (pr.[ID] = ji.[PROJECT])
LEFT OUTER JOIN [cwd_user] as users ON (users.[user_name] = ji.[ASSIGNEE])
WHERE cg.[CREATED] >= CONVERT(datetime, '2021-12-01') AND cg.[CREATED] <= CONVERT(datetime, '2022-01-01') and CONVERT(NVARCHAR(MAX), ci.[NEWSTRING]) = N'Done'
AND itype.pname = 'Incident'
SELECT DISTINCT concat(pr.[pkey], '-', ji.[issuenum]) AS 'Ключ'
,system_t.[NAME] AS 'Контур ИС'
,system_t_t.[NAME] AS 'Критичность системы'
INTO #TT1
FROM
[jiraissue] AS ji
LEFT OUTER JOIN [changegroup] AS cg ON (cg.[issueid] = ji.[id])
LEFT OUTER JOIN [changeitem] AS ci ON (ci.[groupid] = cg.[id]) AND ci.FIELDTYPE='jira' AND ci.FIELD='status'
LEFT OUTER JOIN [app_user] AS au ON (au.[user_key] = cg.[AUTHOR])
LEFT OUTER JOIN [issuetype] AS itype ON (itype.[ID] = ji.[issuetype])
LEFT OUTER JOIN [project] AS pr ON (pr.[ID] = ji.[PROJECT])
LEFT OUTER JOIN [customfieldvalue] AS customfv ON (customfv.[ISSUE] = ji.[ID])
LEFT OUTER JOIN [AO_8542F1_IFJ_OBJ] AS system_t ON (system_t.[ID] = substring(customfv.[STRINGVALUE], PatIndex('%[0-9]%', customfv.[STRINGVALUE]), len(customfv.[STRINGVALUE])))
LEFT OUTER JOIN [AO_8542F1_IFJ_OBJ_ATTR] AS system_attr ON (system_t.[ID] = system_attr.[OBJECT_ID])
LEFT OUTER JOIN [AO_8542F1_IFJ_OBJ_ATTR_VAL] AS system_attr_val ON (system_attr.[ID] = system_attr_val.[OBJECT_ATTRIBUTE_ID])
LEFT OUTER JOIN [AO_8542F1_IFJ_OBJ] AS system_t_t ON (system_attr_val.[REFERENCED_OBJECT_ID] = system_t_t.[ID])
WHERE cg.[CREATED] >= CONVERT(datetime, '2021-12-01') AND cg.[CREATED] <= CONVERT(datetime, '2022-01-01') and CONVERT(NVARCHAR(MAX), ci.[NEWSTRING]) = N'Done'
AND (customfv.[CUSTOMFIELD] = 21003 OR customfv.[CUSTOMFIELD] = 21005)
AND (system_t.[OBJECT_TYPE_ID] = 136 OR system_t.[OBJECT_TYPE_ID] = 303 OR system_t.[OBJECT_TYPE_ID] = 143)
AND system_attr.[OBJECT_TYPE_ATTRIBUTE_ID] = 461
AND itype.pname = 'Incident'
SELECT ji.[issuenum]
,pr_pr.[pname] AS '(project) Project'
INTO #TT2
FROM
[jiraissue] AS ji
LEFT OUTER JOIN [customfieldvalue] AS customfv ON (customfv.[ISSUE] = ji.[ID])
LEFT OUTER JOIN [project] AS pr_pr ON (pr_pr.[ID] = CAST(customfv.[NUMBERVALUE] AS BIGINT))
LEFT OUTER JOIN [changegroup] AS cg ON (cg.[issueid] = ji.[id])
LEFT OUTER JOIN [changeitem] AS ci ON (ci.[groupid] = cg.[id]) AND ci.FIELDTYPE='jira' AND ci.FIELD='status'
LEFT OUTER JOIN [app_user] AS au ON (au.[user_key] = cg.[AUTHOR])
LEFT OUTER JOIN [issuetype] AS itype ON (itype.[ID] = ji.[issuetype])
WHERE cg.[CREATED] >= CONVERT(datetime, '2021-12-01') AND cg.[CREATED] <= CONVERT(datetime, '2022-01-01') and CONVERT(NVARCHAR(MAX), ci.[NEWSTRING]) = N'Done'
AND pr_pr.[pname] is not NULL
SELECT CTE.[Ключ], CTE.[Ссылка], CTE.[П], CTE.[Исполнитель], CTE.[Создан], CTE.[Дата резолюции], CTE2.[(project) Project], CTE1.[Контур ИС], CTE1.[Критичность системы], CTE.[issuenum]
FROM #TT CTE
LEFT OUTER JOIN #TT1 CTE1 ON (CTE1.[Ключ] = CTE.[Ключ])
LEFT OUTER JOIN #TT2 CTE2 ON (CTE2.[issuenum] = CTE.[issuenum])
DROP TABLE IF EXISTS #TT
DROP TABLE IF EXISTS #TT1
DROP TABLE IF EXISTS #TT2
There will be some information for the month before last.
summary of query
The next query is:
WITH CTE AS (
SELECT concat(p.pkey,'-',i.issuenum) AS 'Ключ',
cf.cfname,
cv.textvalue,
ROW_NUMBER() OVER (PARTITION BY i.issuenum ORDER BY i.issuenum) AS RowNumber_SLA
FROM customfield cf,
customfieldvalue cv,
jiraissue i,
project p
WHERE i.project = p.id
AND cv.issue = i.id
AND cv.customfield = cf.id
AND cf.customfieldtypekey = 'com.atlassian.servicedesk:sd-sla-field'
and i.issuenum IN ()
and CHARINDEX('"succeeded":false', TEXTVALUE) >0
)
SELECT CTE.Ключ
FROM CTE
WHERE RowNumber_SLA = 1
The goal is to get tasks where SLA has been failed.
So in and i.issuenum IN () my Python script is putting issue numbers that I got through previous query.
The average execution time is 3 minutes.
So, I want optimize this too, maybe join first query.
Sorry for my English. I'm not an English-speaking person.
P. S. Changing CONVERT(NVARCHAR(MAX), ci.[NEWSTRING]) = N'Done' to ci.[NEWSTRING] = 'Done' causing the error The data types ntext and varchar are incompatible in the equal to operator. Workaround - ci.[NEWSTRING] LIKE 'Done' fixing this.
The first query must be rewrite as :
SELECT DISTINCT
concat(pr.[pkey], '-', ji.[issuenum]) AS 'Ключ',
concat('https://sd.finam.ru/browse/', pr.[pkey], '-', ji.[issuenum]) AS 'Ссылка',
p.[pname] AS 'П',
users.[display_name] AS 'Исполнитель',
CAST(ji.[CREATED] AS SMALLDATETIME) AS 'Создан',
CAST(ji.[RESOLUTIONDATE] AS SMALLDATETIME) AS 'Дата резолюции',
ji.[issuenum]
INTO #TT
FROM [jiraissue] AS ji
INNER JOIN [changegroup] AS cg ON(cg.[issueid] = ji.[id])
INNER JOIN [changeitem] AS ci ON(ci.[groupid] = cg.[id])
AND ci.FIELDTYPE = 'jira'
AND ci.FIELD = 'status'
LEFT OUTER JOIN [app_user] AS au ON(au.[user_key] = cg.[AUTHOR])
INNER JOIN [issuetype] AS itype ON(itype.[ID] = ji.[issuetype])
LEFT OUTER JOIN [priority] AS p ON(p.[ID] = ji.[PRIORITY])
LEFT OUTER JOIN [project] AS pr ON(pr.[ID] = ji.[PROJECT])
LEFT OUTER JOIN [cwd_user] AS users ON(users.[user_name] = ji.[ASSIGNEE])
WHERE cg.[CREATED] >= CONVERT(DATETIME, '2021-12-01')
AND cg.[CREATED] <= CONVERT(DATETIME, '2022-01-01')
AND ci.[NEWSTRING] = 'Done'
AND itype.pname = 'Incident';
False outer joins are converted in INNER and I have aslo eliminate the ugly CONVERT to NVARCHAR(max)
Same troubles appears in the second query...
I am writing a query which is accepting a comma separated string and calculating the sum of transaction. which is working fine as result wise but taking too much time to execute in first attempt. I understand its need tuning but didn't find out the exact reason can any one point me whats wrong with my query.
Declare #IDs nvarchar(max)='1,4,5,6,8,9,43,183'
SELECT isnull(isnull(SUM(FT.PaidAmt),0) - isnull(SUM(CT.PaidAmt),0),0) [Amount], convert(char(10),FT.TranDate,126) [Date]
from FeeTransaction FT
Inner Join (
Select max(P.Id) [Id], P.TranMainId, isnull(SUM(P.AmtToPay),0) [Amt]
From Patient_Account P
Group By P.TranMainId
) PA ON FT.Id = PA.TranMainId
Inner Join Patient_Account XP ON PA.Id = XP.Id
Inner Join Master_Fee MF ON XP.FeeId = MF.Id
INNER Join Master_Patient MP ON FT.PID = MP.Id
Inner Join Master_FeeType TY ON MF.FeeTypeId = TY.Id
Left JOIN FeeTransaction CT on FT.TransactionId = CT.TransactionId AND CT.TranDate between '2019'+'08'+'01' and '2019'+'08'+'31' and CT.[Status] <> 'A' AND isnull(CT.IsCancel,0) = 1
Where convert(nvarchar,FT.TranDate,112) between '2019'+'08'+'01' and '2019'+'08'+'31' AND FT.[Status] = 'A' AND XP.FeeId in (SELECT val FROM dbo.f_split(#IDs, ','))
AND isnull(FT.IsCancel,0) = 0 AND FT.EntryBy = 'rajan'
Group By convert(char(10),FT.TranDate,126)
I would rephrase the query a bit:
select coalesce(SUM(FT.PaidAmt), 0) - coalesce(SUM(CT.PaidAmt), 0)as [Amount],
convert(char(10),FT.TranDate,126) [Date]
from FeeTransaction FT join
(select xp.*,
coalesce(sum(p.amttopay) over (TranMainId), 0) as amt
from Patient_Account XP ON PA.Id = XP.Id
) xp join
Master_Fee MF
on XP.FeeId = MF.Id join
Master_Patient MP
on FT.PID = MP.Id join
Master_FeeType TY
on MF.FeeTypeId = TY.Id left join
FeeTransaction CT
on FT.TransactionId = CT.TransactionId and
CT.TranDate between '20190801' and '20190831' and
CT.[Status] <> 'A' and
CT.IsCanel = 1
where FT.TranDate >= '20190801' and and
FT.TranDate < '20190901'
FT.[Status] = 'A' AND
XP.FeeId in (SELECT val FROM dbo.f_split(#IDs, ',')) and
(FT.IsCancel = 0 or FT.IsCancel IS NULL) and
FT.EntryBy = 'rajan'
Group By convert(char(10), FT.TranDate, 126)
Then for this version, you specifically an index on FeeTransaction(EntryBy, Status, TranDate, Cancel).
Note the following changes:
You do not need to aggregate Patient_Account as a subquery. Window functions are quite convenient.
Your date comparisons preclude the use of indexes. Converting dates to strings is a bad practice in general.
You have over-used isnull().
I assume that the appropriate indexes are in place for the joins.
I would use STRING_SPLIT and Common Table Expressions and do away with date conversions:
Declare #IDs nvarchar(max)='1,4,5,6,8,9,43,183'
;WITH CTE_ID AS
(
SELECT value AS ID FROM STRING_SPLIT(#IDs, ',');)
),
MaxPatient
AS
(
SELECT MAX(P.Id) [Id], P.TranMainId, isnull(SUM(P.AmtToPay),0) [Amt]
From Patient_Account P
Group By P.TranMainId
)
SELECT isnull(isnull(SUM(FT.PaidAmt),0) - isnull(SUM(CT.PaidAmt),0),0) As [Amount],
convert(char(10),FT.TranDate,126) [Date]
FROM FeeTransaction FT
INNER JOIN MaxPatient PA
ON FT.Id = PA.TranMainId
INNER JOIN Patient_Account XP
ON PA.Id = XP.Id
INNER JOIN Master_Fee MF
ON XP.FeeId = MF.Id
INNER Join Master_Patient MP
ON FT.PID = MP.Id
INNER JOIN Master_FeeType TY
ON MF.FeeTypeId = TY.Id
INNER JOIN CTE_ID
ON XP.FeeId = CTE_ID.ID
LEFT JOIN FeeTransaction CT
ON FT.TransactionId = CT.TransactionId AND
CT.TranDate >= '20190801' AND CT.TranDate < '20190831' AND
CT.[Status] <> 'A' AND isnull(CT.IsCancel,0) = 1
WHERE FT.TranDate >= '20190801' and FT.TranDate < '20190831' AND
FT.[Status] = 'A' AND
ISNULL(FT.IsCancel,0) = 0 AND
FT.EntryBy = 'rajan'
GROUP BY CAST(FT.TranDate AS Date)
Not only is your query slow, but it appear that it is giving incorrect output.
i) When you are not using any column of Patient_Account in your resultset then why are you writing this sub query?
Select max(P.Id) [Id], P.TranMainId, isnull(SUM(P.AmtToPay),0) [Amt]
From Patient_Account P
Group By P.TranMainId
ii) Avoid using <>.So Status must be either 'A' or 'I'
so write this instead CT.[Status] = 'I'
iii) What is the correct data type of TranDate ?Don't use function in where condition. .
iv) No need of isnull(CT.IsCancel,0) = 1,instead write CT.IsCancel = 1
So my script is just outline, but it is easy to understand.
Declare #IDs nvarchar(max)='1,4,5,6,8,9,43,183'
create table #temp(id int)
insert into #temp(id)
SELECT val FROM dbo.f_split(#IDs, ',')
declare #FromDate Datetime='2019-08-01'
declare #toDate Datetime='2019-08-31'
-- mention all column of FeeTransaction that you need in this query along with correct data type
-- Store TranDate in this manner convert(char(10),FT.TranDate,126) in this table
create table #Transaction()
select * from FeeTransaction FT
where FT.TranDate>=#FromDate and FT.TranDate<#toDate
and exists(select 1 from #temp t where t .val=ft.id)
-- mention all column of Patient_Account that you need in this query along with correct data type
create table #Patient_Account()
Select max(P.Id) [Id], P.TranMainId, isnull(SUM(P.AmtToPay),0) [Amt]
From Patient_Account P
where exists(select 1 from #Transaction T where t.id=PA.TranMainId)
Group By P.TranMainId
SELECT isnull(isnull(SUM(FT.PaidAmt),0) - isnull(SUM(CT.PaidAmt),0),0) [Amount], TranDate [Date]
from #Transaction FT
Inner Join #Patient_Account XP ON PA.Id = XP.Id
Inner Join Master_Fee MF ON XP.FeeId = MF.Id
INNER Join Master_Patient MP ON FT.PID = MP.Id
Inner Join Master_FeeType TY ON MF.FeeTypeId = TY.Id
Left JOIN #Transaction CT on FT.TransactionId = CT.TransactionId AND CT.[Status] = 'I' AND CT.IsCancel = 1
Where AND FT.[Status] = 'A' AND XP.FeeId in (SELECT val FROM #temp t)
AND FT.IsCancel = 0 AND FT.EntryBy = 'rajan'
Group By TranDate
I am trying to sort the record on milestone id coloumn but it is throwing error at order by in subquery giving error as "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."
CREATE PROCEDURE [dbo].[spGetALLStudyCodedtls]
(
#StudyCodeId VARCHAR(MAX)
)
AS
BEGIN
SELECT X.[IsActive]
--scd.[StudyCodeId]
,
X.[StudyCode],
X.[ProductName],
X.[TherapyName],
X.[Dosage],
X.[StudyType],
X.[Condition],
X.[CountryName],
X.[CRO],
X.[Design],
X.[DesignTag],
X.[RnD ProjManager],
X.[Project Manager],
X.[IPDFillingTimeline],
X.[Comments],
X.[MileStoneId],
X.[Milestone],
X.[Category],
X.[BaseLineDate],
X.[ActualDate]
FROM (
SELECT sc.IsActive
--scd.[StudyCodeId]
,
scd.[StudyCode],
pm.ProductName,
tm.TherapyName,
dm.Dosage,
stm.StudyType,
com.Condition,
cn.CountryName,
crm.CRO,
dsm.Design,
dtm.DesignTag,
ud.[user_name] AS 'RnD ProjManager',
udd.[user_name] AS 'Project Manager',
scd.[IPDFillingTimeline],
scd.[Remarks] AS 'Comments',
mm.MileStoneId,
mm.MileStoneName AS 'Milestone',
mm.Category AS 'Category',
sc.[BaseLineDate],
sc.[ActualDate]
FROM [PMS].[dbo].[StudyCodeDetails] scd
INNER JOIN [dbo].[StudyCodeToMileStone] sc ON scd.StudyCodeId = sc.StudyCodeId
INNER JOIN [dbo].[MileStoneMaster] mm ON sc.MileStoneId = mm.MileStoneId
INNER JOIN dbo.ProductMaster pm ON scd.ProductId = pm.ProductId
INNER JOIN dbo.TherapyMaster tm ON tm.TherapyId = scd.TherapyId
INNER JOIN dbo.DosageMaster dm ON dm.DosageId = scd.DosageId
INNER JOIN dbo.CountryMaster cn ON cn.CountryId = scd.CountryId
INNER JOIN dbo.[User_Dtls] ud ON ud.Pk_ID = scd.RnDProjManagerId
INNER JOIN dbo.[User_Dtls] udd ON udd.Pk_ID = scd.ProjectManagerId
INNER JOIN dbo.CroMaster crm ON crm.CroId = scd.CRO
INNER JOIN dbo.DesignMaster dsm ON dsm.DesignId = scd.DesignId
INNER JOIN dbo.DesignTagMaster dtm ON dtm.DesignTagId = scd.DesignTagId
INNER JOIN dbo.StudyTypeMaster stm ON stm.StudyTypeId = scd.StudyTypeId
INNER JOIN dbo.ConditionMaster com ON com.ConditionId = scd.Condition
WHERE scd.StudyCodeId IN (
SELECT CAST(Item AS INTEGER)
FROM [dbo].[SplitString](#StudyCodeId, ',')
)
AND mm.[AdditionalPayment] = 0
ORDER BY mm.MileStoneId
) AS X
GROUP BY X.[IsActive]
--scd.[StudyCodeId]
,
X.[StudyCode],
X.[ProductName],
X.[TherapyName],
X.[Dosage],
X.[StudyType],
X.[Condition],
X.[CountryName],
X.[CRO],
X.[Design],
X.[DesignTag],
X.[RnD ProjManager],
X.[Project Manager],
X.[IPDFillingTimeline],
X.[Comments],
X.[MileStoneId],
X.[Milestone],
X.[Category],
X.[BaseLineDate],
X.[ActualDate]
END
Please try this one:
CREATE PROCEDURE [dbo].[spGetALLStudyCodedtls]
(
#StudyCodeId VARCHAR(MAX)
)
AS
BEGIN
SELECT X.[IsActive]
--scd.[StudyCodeId]
,
X.[StudyCode],
X.[ProductName],
X.[TherapyName],
X.[Dosage],
X.[StudyType],
X.[Condition],
X.[CountryName],
X.[CRO],
X.[Design],
X.[DesignTag],
X.[RnD ProjManager],
X.[Project Manager],
X.[IPDFillingTimeline],
X.[Comments],
X.[MileStoneId],
X.[Milestone],
X.[Category],
X.[BaseLineDate],
X.[ActualDate]
FROM (
SELECT t1.IsActive,
t1.[StudyCode],
t2.ProductName,
t2.TherapyName,
t2.Dosage,
t2.StudyType,
t2.Condition,
t2.CountryName,
t2.CRO,
t2.Design,
t2.DesignTag,
t2.[user_name] AS 'RnD ProjManager',
t2.[user_name] AS 'Project Manager',
t1.[IPDFillingTimeline],
scd.[Remarks] AS 'Comments',
t2.MileStoneId,
t2.MileStoneName AS 'Milestone',
t2.Category AS 'Category',
t1.[BaseLineDate],
t1.[ActualDate]
FROM
(
SELECT sc.IsActive,
scd.[StudyCode],
scd.[IPDFillingTimeline],
scd.[Remarks] AS 'Comments',
sc.[BaseLineDate],
sc.[ActualDate],
sc.MileStoneId
FROM [PMS].[dbo].[StudyCodeDetails] scd
INNER JOIN [dbo].[StudyCodeToMileStone] sc
ON scd.StudyCodeId = sc.StudyCodeId
) AS t1
CROSS APPLY (
SELECT pm.ProductName,
tm.TherapyName,
dm.Dosage,
stm.StudyType,
com.Condition,
cn.CountryName,
crm.CRO,
dsm.Design,
dtm.DesignTag,
ud.[user_name] AS 'RnD ProjManager',
udd.[user_name] AS 'Project Manager',
mm.MileStoneId,
mm.MileStoneName AS 'Milestone',
mm.Category AS 'Category',
FROM [dbo].[MileStoneMaster] mm
INNER JOIN dbo.ProductMaster pm ON scd.ProductId = pm.ProductId
INNER JOIN dbo.TherapyMaster tm ON tm.TherapyId = scd.TherapyId
INNER JOIN dbo.DosageMaster dm ON dm.DosageId = scd.DosageId
INNER JOIN dbo.CountryMaster cn ON cn.CountryId = scd.CountryId
INNER JOIN dbo.[User_Dtls] ud ON ud.Pk_ID = scd.RnDProjManagerId
INNER JOIN dbo.[User_Dtls] udd ON udd.Pk_ID = scd.ProjectManagerId
INNER JOIN dbo.CroMaster crm ON crm.CroId = scd.CRO
INNER JOIN dbo.DesignMaster dsm ON dsm.DesignId = scd.DesignId
INNER JOIN dbo.DesignTagMaster dtm ON dtm.DesignTagId = scd.DesignTagId
INNER JOIN dbo.StudyTypeMaster stm ON stm.StudyTypeId = scd.StudyTypeId
INNER JOIN dbo.ConditionMaster com ON com.ConditionId = scd.Condition
WHERE scd.StudyCodeId IN (
SELECT CAST(Item AS INTEGER)
FROM [dbo].[SplitString](#StudyCodeId, ',')
)
AND mm.[AdditionalPayment] = 0
AND mm.MileStoneId = t1.MileStoneId
ORDER BY mm.MileStoneId
) AS t2
) AS X
GROUP BY X.[IsActive]
--scd.[StudyCodeId]
,
X.[StudyCode],
X.[ProductName],
X.[TherapyName],
X.[Dosage],
X.[StudyType],
X.[Condition],
X.[CountryName],
X.[CRO],
X.[Design],
X.[DesignTag],
X.[RnD ProjManager],
X.[Project Manager],
X.[IPDFillingTimeline],
X.[Comments],
X.[MileStoneId],
X.[Milestone],
X.[Category],
X.[BaseLineDate],
X.[ActualDate]
END
I probably messed that title up! So I have a column called "programID" and I want another column to tell me the most recent date an order was placed using the programID. I think I'd need a subcolumn but the problem is how do I use the row's programID so that it matches the programID for the same row?
DECLARE #ClientIDs varchar(4) = 6653;
DECLARE #ProgramStatus char(1) = 'Y'; -- Y, N, or R
SELECT
rcp.RCPID AS ProgramID
, rcp.RCPName AS Program
, rcp.RCPActive AS ProgramStatus
, aa.AACustomCardInternalReview AS VCCP
, aa.AAJobNo AS AAJobNo
, aas.AASName AS AAStatus
, rcp.RCPOpsApproved AS OpsApproved
, clt.CltID AS ClientID
, rcp.RCPSignatureRequired AS SignatureRequired
, st.STEnumValue AS DefaultShipType
, rcp.RCPShipMethodOverrideType AS ShipTypeOverride
,aa.AANetworkProgramID
,(Select max(cdconfirmationdate) from carddet where ) --can't figure this part out
FROM
RetailerCardProgram rcp WITH (NOLOCK)
INNER JOIN ClientRetailerMap crm WITH (NOLOCK)
ON crm.CRMRetailerID = rcp.RCPRetailerID
INNER JOIN Client clt WITH(NOLOCK)
ON clt.CltID = crm.CRMCltID
LEFT JOIN AssociationApproval aa WITH (NOLOCK)
ON aa.AARetailerID = rcp.RCPRetailerID
AND aa.AABin = rcp.RCPBin6
AND aa.AAFrontOfPlasticTemplateID = rcp.RCPFOCTemplateID
AND aa.AABackOfPlasticTemplateID = rcp.RCPBOCTemplateID
AND ISNULL(aa.AACardID, 0) = ISNULL(rcp.RCPDefaultPlasticCardID, 0)
-- AND LOWER(rcp.RCPName) NOT LIKE '%do not use%' -- Needed for AA Job Number 1594
LEFT JOIN AssociationApprovalStatus aas WITH (NOLOCK)
ON aas.AASID = aa.AAAssociationApprovalStatusID
LEFT JOIN OpenLoopAssociation ola WITH (NOLOCK)
ON ola.OLAID=rcp.RCPOLAID
LEFT JOIN ClientCardProgramMap ccpm WITH (NOLOCK)
ON ccpm.CCPMCardProgramID = rcp.RCPID
AND ccpm.CCPMClientID = clt.CltID
LEFT JOIN TippingModule tm WITH (NOLOCK)
ON tm.TMid = rcp.RCPTippingModuleID
LEFT JOIN GiftCardTemplate fgt WITH (NOLOCK)
ON fgt.gtid = rcp.RCPFOCTemplateID
AND fgt.GTPage='P'
LEFT JOIN GiftCardTemplate bgt WITH (NOLOCK)
ON bgt.gtid = rcp.RCPBOCTemplateID
AND bgt.GTPage='PB'
LEFT JOIN Card c WITH (NOLOCK)
ON c.CardID = rcp.RCPDefaultCarrierID
LEFT JOIN CardType ct WITH (NOLOCK)
ON ct.CTID = c.CardTypeID
LEFT JOIN RetailerCardProgramTCSheetMap rtm1 WITH (NOLOCK)
ON rtm1.RTMRCPID = rcp.RCPID
AND rtm1.RTMInsertOrder = 1
LEFT JOIN RetailerCardProgramTCSheetMap rtm2 WITH (NOLOCK)
ON rtm2.RTMRCPID = rcp.RCPID
AND rtm2.RTMInsertOrder = 2
LEFT JOIN RetailerCardProgramTCSheetMap rtm3 WITH (NOLOCK)
ON rtm3.RTMRCPID = rcp.RCPID
AND rtm3.RTMInsertOrder = 3
LEFT JOIN RetailerCardProgramTCSheetMap rtm4 WITH (NOLOCK)
ON rtm4.RTMRCPID = rcp.RCPID
AND rtm4.RTMInsertOrder = 4
LEFT JOIN TCSheet i1 WITH (NOLOCK)
ON i1.TCSID = rtm1.RTMTCSID
LEFT JOIN TCSheet i2 WITH (NOLOCK)
ON i2.TCSID = rtm2.RTMTCSID
LEFT JOIN TCSheet i3 WITH (NOLOCK)
ON i3.TCSID = rtm3.RTMTCSID
LEFT JOIN TCSheet i4 WITH (NOLOCK)
ON i4.TCSID = rtm4.RTMTCSID
LEFT JOIN ShipType st WITH (NOLOCK)
ON st.STId = rcp.RCPDefaultShipTypeID
WHERE
clt.CltID IN (#ClientIDs) -- 6653 and 6657.
AND rcp.RCPActive IN (#ProgramStatus)
ORDER BY
AAJobNo
, Program
You want to join with a nested select on the table carddet. I'm inferring that RCPID is the relationship between carddet and your main table RetainerCardProgram...
SELECT rcp.RCPID AS ProgramID,
date.MAXDATE AS MaxDate,
rest of your columns...
FROM RetailerCardProgram rcp WITH (NOLOCK)
INNER JOIN (
SELECT RCPID, MAX(cdconfirmationdate) as 'MAXDATE'
FROM carddet
GROUP BY RCPID
) date on date.RCPID = rcp.RCPID
rest of query...
You may want a left join if not all IDs have a date in carddet.
Obligatory addition: Also your use of NOLOCK is a bit terrifying. See http://blogs.sqlsentry.com/aaronbertrand/bad-habits-nolock-everywhere/
I just need to select one more field in my query that is the date... but it's a subquery and i'm using a count field... and because of it i need to use the GROUP BY Clause... But i can't group by my subquery and the query is returning errors...
SELECT
X.NROF,
Z.NMGUERFORN,
C.CDCOMPRADO,
C.CDCOORDENA,
E.CDFUP,
count(*) AS ocorrencias
--(select TOP 1 DTPROGENTR from CMPENL0 C (NOLOCK) where X.NRPEDICOMP = C.NRPEDICOMP AND X.NRITEMPECO = C.NRITEMPECO) AS DTPROGENTR
FROM CMPCIL0 X (NOLOCK)
inner join CMPCCL0 Y (NOLOCK) on X.NRPEDICOMP = Y.NRPEDICOMP
inner join CMFRNL0 Z (NOLOCK) on Y.CDFORNECED1 = Z.CDFORNECED1
inner join CMSCPL0 M (NOLOCK) on X.NRSOLICOMP = M.NRSOLICOMP AND X.NRITEMSC = M.NRITEMSC
inner join CMPENL0 N (NOLOCK) on X.NRPEDICOMP = N.NRPEDICOMP AND X.NRITEMPECO = N.NRITEMPECO
inner join CMMATL0 A (NOLOCK) on X.CDMATERIAL = A.CDMATERIAL
inner join cmcomL0 c (NOLOCK) on c.cdcomprado = y.cdcomprado
LEFT JOIN AMCSPL0 D (NOLOCK) ON D.SCPE_NRSOLICOMP = X.NRSOLICOMP AND D.SCPE_NRITEMSC=X.NRITEMSC
LEFT JOIN CMFUPL0 E (NOLOCK) ON E.CDFORNECED1 = Z.CDFORNECED1
LEFT JOIN CMPFIL0 H ON Z.CDFORNECED1 = H.CDFORNECED1 AND X.NRIDENTIFI = H.NRIDENTIFI and H.DTVALIDADE > Y.DTEFETPECO
LEFT JOIN CMPENL0 F ON (X.NRPEDICOMP = F.NRPEDICOMP AND X.NRITEMPECO = F.NRITEMPECO)
WHERE X.CDSTATUS = 'P' and X.NROF <> 0
group by X.NROF,Z.NMGUERFORN,C.CDCOMPRADO,C.CDCOORDENA,E.CDFUP--,DTPROGENTR
order by 6 desc
The commented parts are the code im trying to include to select the field, but it is giving me errors..
The problem is that you use aliases in your where clause of select sub-query. Aliases cannot be referenced on the same level in the query. You should use full qualified names and the sub-query should look something like that:
(select TOP 1 DTPROGENTR from CMPENL0 C (NOLOCK) where X.NRPEDICOMP = CMPENL0.NRPEDICOMP AND X.NRITEMPECO = CMPENL0.NRITEMPECO) AS DTPROGENTR
If your sql-server supports common table expressions you can try that:
;WITH cte AS
(
SELECT ROW_NUMBER() OVER(PARTITION BY NRPEDICOMP, NRITEMPECO ORDER BY NRPEDICOMP) row_num
,DTPROGENTR
,NRPEDICOMP
,NRITEMPECO
FROM CMPENL0 (NOLOCK)
)
SELECT
X.NROF,
Z.NMGUERFORN,
C.CDCOMPRADO,
C.CDCOORDENA,
E.CDFUP,
count(*) AS ocorrencias
cte.DTPROGENTR
FROM CMPCIL0 X (NOLOCK)
inner join CMPCCL0 Y (NOLOCK) on X.NRPEDICOMP = Y.NRPEDICOMP
inner join CMFRNL0 Z (NOLOCK) on Y.CDFORNECED1 = Z.CDFORNECED1
inner join CMSCPL0 M (NOLOCK) on X.NRSOLICOMP = M.NRSOLICOMP AND X.NRITEMSC = M.NRITEMSC
inner join CMPENL0 N (NOLOCK) on X.NRPEDICOMP = N.NRPEDICOMP AND X.NRITEMPECO = N.NRITEMPECO
inner join CMMATL0 A (NOLOCK) on X.CDMATERIAL = A.CDMATERIAL
inner join cmcomL0 c (NOLOCK) on c.cdcomprado = y.cdcomprado
LEFT JOIN AMCSPL0 D (NOLOCK) ON D.SCPE_NRSOLICOMP = X.NRSOLICOMP AND D.SCPE_NRITEMSC=X.NRITEMSC
LEFT JOIN CMFUPL0 E (NOLOCK) ON E.CDFORNECED1 = Z.CDFORNECED1
LEFT JOIN CMPFIL0 H ON Z.CDFORNECED1 = H.CDFORNECED1 AND X.NRIDENTIFI = H.NRIDENTIFI and H.DTVALIDADE > Y.DTEFETPECO
LEFT JOIN CMPENL0 F ON X.NRPEDICOMP = F.NRPEDICOMP AND X.NRITEMPECO = F.NRITEMPECO
LEFT JOIN cte ON X.NRPEDICOMP = cte.NRPEDICOMP AND X.NRITEMPECO = cte.NRITEMPECO AND cte.row_num = 1
WHERE X.CDSTATUS = 'P' and X.NROF <> 0
group by X.NROF,Z.NMGUERFORN,C.CDCOMPRADO,C.CDCOORDENA,E.CDFUP, cte.DTPROGENTR
order by 6 desc