How do I select the max of several fields in the middle of a one to many to many query - sql
All,
I have this query below which is a one to many to many relationship.
The relationship is as such, a story can have multiple tasks (1>M) each task can have multiple time entries (M-M)
I want to get the 1st occurrence of 3 fields in the tasks section and null the remainder for each story. So for example;
Story 1234
Tasks 12, 13, 14,15
Time entry 120, 121, 134, 135 etc....
There are 3 fields in tasks OptimisticEstimate, ProbableEstimate and Pessimistic Estimate that get repeated at the task level when Time entry table is linked in to the query (as it should be).
I want to get the 1st occurrence of those fields for each task and leave any other occurrence NULL so that when we sum it up the estimated don't get summed along with the hours from time entry.
Hopefully that is clear.
WITH
WorkItem_CTE AS
(-- Child Level (Task)
SELECT wi1.AreaID
,a.Name AS AreaName
,wi1.ProjectID
,wi1.IterationID
-- Work Items
,DATEADD(HOUR, DATEDIFF(HOUR, GETUTCDATE(), GETDATE()),wi1.CreatedDateUtc) AS WorkItemCreatedDTS
,wi1.WorkItemID
,wi1.[Type] AS WorkItemType
,wi1.Name AS WorkItemName
,wi1.[Status] AS WorkItemStatus
,wi1.[Priority] AS WorkItemPriority
,wi1.Complexity
,wi1.Estimate
-- Tasks
,DATEADD(HOUR, DATEDIFF(HOUR, GETUTCDATE(), GETDATE()),wi2.CreatedDateUtc) AS TaskCreatedDTS
,wi2.WorkItemID AS TaskID
,wi2.Name AS TaskName
,wi2.[Status] AS TaskStatus
,wi2.AssignedTo AS TaskAssignedTo
,wi2.EstimateOptimistic
,Case When wi2.EstimateProbable IS NULL Then (wi2.EstimateOptimistic + wi2.EstimatePessimistic)/2 Else wi2.EstimateProbable End As EstimateProbable
,wi2.EstimatePessimistic
,wi2.WorkCompleted
,wi2.WorkRemaining
FROM dbo.WorkItem wi1 WITH (NOLOCK)
INNER JOIN dbo.WorkItem wi2 WITH (NOLOCK)
ON wi1.WorkItemID = wi2.ParentID
AND wi2.[Status] <> 'Deleted'
LEFT OUTER JOIN dbo.Area a WITH (NOLOCK)
ON wi1.AreaID = a.AreaID
--LEFT OUTER JOIN dbo.Project p WITH (NOLOCK)
-- ON wi1.ProjectID = p.ProjectID
WHERE wi1.[Status] <> 'Deleted'
UNION ALL
-- Parent level (Story, Bug, Feedback)
SELECT wi1.AreaID
,a.Name AS AreaName
,wi1.ProjectID
,wi1.IterationID
-- Work Items
,DATEADD(HOUR, DATEDIFF(HOUR, GETUTCDATE(), GETDATE()),wi1.CreatedDateUtc) AS WorkItemCreatedDTS
,wi1.WorkItemID
,wi1.[Type] AS WorkItemType
,wi1.Name AS WorkItemName
,wi1.[Status] AS WorkItemStatus
,wi1.[Priority] AS WorkItemPriority
,wi1.Complexity
,wi1.Estimate
-- Tasks
,DATEADD(HOUR, DATEDIFF(HOUR, GETUTCDATE(), GETDATE()),wi2.CreatedDateUtc) AS TaskCreatedDTS
,wi2.WorkItemID AS TaskID
,wi2.Name AS TaskName
,wi2.[Status] AS TaskStatus
,wi2.AssignedTo AS TaskAssignedTo
,wi2.EstimateOptimistic
,Case When wi2.EstimateProbable IS NULL Then (wi2.EstimateOptimistic + wi2.EstimatePessimistic)/2 Else wi2.EstimateProbable End As EstimateProbable
,wi2.EstimatePessimistic
,wi2.WorkCompleted
,wi2.WorkRemaining
FROM dbo.WorkItem wi1 WITH (NOLOCK)
LEFT OUTER JOIN dbo.WorkItem wi2 WITH (NOLOCK)
ON wi1.WorkItemID = wi2.ParentID
AND wi2.[Status] <> 'Deleted'
LEFT OUTER JOIN dbo.Area a WITH (NOLOCK)
ON wi1.AreaID = a.AreaID
WHERE wi1.[Type] <> 'Task'
AND wi1.[Status] <> 'Deleted'
AND wi2.ParentID IS NULL
),
--Time Entry for Tasks
TimeEntry_CTE As
(SELECT te.WorkItemID
,te.ProjectID
,te.Date
,te.Hours
,te.CreatedBy
,te.CreatedDateUtc
,te.LastModifiedBy
,te.LastModifiedDateUtc
,te.Note
FROM TimeEntry te
)
SELECT wi.AreaID
,wi.AreaName
,wi.ProjectID
,p.Name AS ProjectName
,wi.WorkItemCreatedDTS
,wi.WorkItemID
,wi.WorkItemType
,wi.WorkItemName
,wi.WorkItemStatus
,wi.WorkItemPriority
,wi.Complexity
,wi.Estimate AS StoryEstimate
,wi.TaskCreatedDTS
,wi.TaskID
,wi.TaskName
,wi.EstimateOptimistic
,wi.EstimateProbable
,wi.EstimatePessimistic
,wi.TaskStatus
,wi.TaskAssignedTo
,wi.WorkCompleted
,wi.WorkRemaining
,te.WorkItemID as TimeWorkItemID
,te.ProjectID
,te.Date
,te.Hours
,te.CreatedBy
,te.CreatedDateUtc
,te.LastModifiedBy
,te.LastModifiedDateUtc
,te.Note
FROM WorkItem_CTE wi WITH (NOLOCK)
LEFT OUTER JOIN dbo.Project p WITH (NOLOCK)
ON wi.ProjectID = p.ProjectID
inner Join TimeEntry_CTE te With (nolock)
ON wi.TaskID = te.WorkItemID
Thanks in Advance for any help.
Revised Code based on suggestions. Closer but not quite right.
WITH
WorkItem_CTE AS
(-- Child Level (Task)
SELECT wi1.AreaID
,a.Name AS AreaName
,wi1.ProjectID
,wi1.IterationID
-- Work Items
,DATEADD(HOUR, DATEDIFF(HOUR, GETUTCDATE(), GETDATE()),wi1.CreatedDateUtc) AS WorkItemCreatedDTS
,wi1.WorkItemID
,wi1.[Type] AS WorkItemType
,wi1.Name AS WorkItemName
,wi1.[Status] AS WorkItemStatus
,wi1.[Priority] AS WorkItemPriority
,wi1.Complexity
,wi1.Estimate
-- Tasks
,DATEADD(HOUR, DATEDIFF(HOUR, GETUTCDATE(), GETDATE()),wi2.CreatedDateUtc) AS TaskCreatedDTS
,wi2.WorkItemID AS TaskID
,wi2.Name AS TaskName
,wi2.[Status] AS TaskStatus
,wi2.AssignedTo AS TaskAssignedTo
,wi2.EstimateOptimistic
,Case When wi2.EstimateProbable IS NULL Then (wi2.EstimateOptimistic + wi2.EstimatePessimistic)/2 Else wi2.EstimateProbable End As EstimateProbable
,wi2.EstimatePessimistic
,wi2.WorkCompleted
,wi2.WorkRemaining
FROM dbo.WorkItem wi1 WITH (NOLOCK)
INNER JOIN dbo.WorkItem wi2 WITH (NOLOCK)
ON wi1.WorkItemID = wi2.ParentID
AND wi2.[Status] <> 'Deleted'
LEFT OUTER JOIN dbo.Area a WITH (NOLOCK)
ON wi1.AreaID = a.AreaID
--LEFT OUTER JOIN dbo.Project p WITH (NOLOCK)
-- ON wi1.ProjectID = p.ProjectID
WHERE wi1.[Status] <> 'Deleted'
UNION ALL
-- Parent level (Story, Bug, Feedback)
SELECT wi1.AreaID
,a.Name AS AreaName
,wi1.ProjectID
,wi1.IterationID
-- Work Items
,DATEADD(HOUR, DATEDIFF(HOUR, GETUTCDATE(), GETDATE()),wi1.CreatedDateUtc) AS WorkItemCreatedDTS
,wi1.WorkItemID
,wi1.[Type] AS WorkItemType
,wi1.Name AS WorkItemName
,wi1.[Status] AS WorkItemStatus
,wi1.[Priority] AS WorkItemPriority
,wi1.Complexity
,wi1.Estimate
-- Tasks
,DATEADD(HOUR, DATEDIFF(HOUR, GETUTCDATE(), GETDATE()),wi2.CreatedDateUtc) AS TaskCreatedDTS
,wi2.WorkItemID AS TaskID
,wi2.Name AS TaskName
,wi2.[Status] AS TaskStatus
,wi2.AssignedTo AS TaskAssignedTo
,wi2.EstimateOptimistic
,Case When wi2.EstimateProbable IS NULL Then (wi2.EstimateOptimistic + wi2.EstimatePessimistic)/2 Else wi2.EstimateProbable End As EstimateProbable
,wi2.EstimatePessimistic
,wi2.WorkCompleted
,wi2.WorkRemaining
FROM dbo.WorkItem wi1 WITH (NOLOCK)
LEFT OUTER JOIN dbo.WorkItem wi2 WITH (NOLOCK)
ON wi1.WorkItemID = wi2.ParentID
AND wi2.[Status] <> 'Deleted'
LEFT OUTER JOIN dbo.Area a WITH (NOLOCK)
ON wi1.AreaID = a.AreaID
WHERE wi1.[Type] <> 'Task'
AND wi1.[Status] <> 'Deleted'
AND wi2.ParentID IS NULL
),
--Time Entry for Tasks
TimeEntry_CTE As
(SELECT te.WorkItemID
,te.ProjectID
,te.Date
,te.Hours
,te.CreatedBy
,te.CreatedDateUtc
,te.LastModifiedBy
,te.LastModifiedDateUtc
,te.Note
FROM TimeEntry te
),
wi_CTE As
(SELECT wi.AreaID
,wi.AreaName
,wi.ProjectID
,p.Name AS ProjectName
,wi.WorkItemCreatedDTS
,wi.WorkItemID
,wi.WorkItemType
,wi.WorkItemName
,wi.WorkItemStatus
,wi.WorkItemPriority
,wi.Complexity
,wi.Estimate AS StoryEstimate
,wi.TaskCreatedDTS
,wi.TaskID
,wi.TaskName
,wi.EstimateOptimistic
,wi.EstimateProbable
,wi.EstimatePessimistic
,wi.TaskStatus
,wi.TaskAssignedTo
,wi.WorkCompleted
,wi.WorkRemaining
,te.WorkItemID as TimeWorkItemID
,te.ProjectID TimeProjectID
,te.Date
,Sum(te.Hours) Hours
,te.CreatedBy
,te.CreatedDateUtc
,te.LastModifiedBy
,te.LastModifiedDateUtc
,te.Note
FROM WorkItem_CTE wi WITH (NOLOCK)
LEFT OUTER JOIN dbo.Project p WITH (NOLOCK)
ON wi.ProjectID = p.ProjectID
inner Join TimeEntry_CTE te With (nolock)
ON wi.TaskID = te.WorkItemID
--where wi.WorkItemID =94
Group By
wi.AreaID
,wi.AreaName
,wi.ProjectID
,p.Name
,wi.WorkItemCreatedDTS
,wi.WorkItemID
,wi.WorkItemType
,wi.WorkItemName
,wi.WorkItemStatus
,wi.WorkItemPriority
,wi.Complexity
,wi.Estimate
,wi.TaskCreatedDTS
,wi.TaskID
,wi.TaskName
,wi.EstimateOptimistic
,wi.EstimateProbable
,wi.EstimatePessimistic
,wi.TaskStatus
,wi.TaskAssignedTo
,wi.WorkCompleted
,wi.WorkRemaining
,te.WorkItemID
,te.ProjectID
,te.Date
,te.Hours
,te.CreatedBy
,te.CreatedDateUtc
,te.LastModifiedBy
,te.LastModifiedDateUtc
,te.Note),
cte AS (SELECT wi_cte.*, ROW_NUMBER() OVER(PARTITION BY WorkItemID, TaskID ORDER BY TimeWorkItemID) RN
FROM wi_CTE
)
SELECT
AreaID
,AreaName
,ProjectID
,ProjectName
,WorkItemCreatedDTS
,WorkItemID
,WorkItemType
,WorkItemName
,WorkItemStatus
,WorkItemPriority
,Complexity
,StoryEstimate
,TaskCreatedDTS
,TaskID
,TaskName
,EstimateOptimistic
,EstimateProbable
,EstimatePessimistic
,TaskStatus
,TaskAssignedTo
,WorkCompleted
,WorkRemaining
,WorkItemID
,ProjectID
,Date
,Hours
,CreatedBy
,CreatedDateUtc
,LastModifiedBy
,LastModifiedDateUtc
,Note
,RN
,SUM(CASE WHEN RN = 1 THEN Hours END) AS SumTime
FROM cte
Where RN=1
GROUP BY
AreaID
,AreaName
,ProjectID
,ProjectName
,WorkItemCreatedDTS
,WorkItemID
,WorkItemType
,WorkItemName
,WorkItemStatus
,WorkItemPriority
,Complexity
,StoryEstimate
,TaskCreatedDTS
,TaskID
,TaskName
,EstimateOptimistic
,EstimateProbable
,EstimatePessimistic
,TaskStatus
,TaskAssignedTo
,WorkCompleted
,WorkRemaining
,WorkItemID
,ProjectID
,Date
,Hours
,CreatedBy
,CreatedDateUtc
,LastModifiedBy
,LastModifiedDateUtc
,Note
,RN
What I get
ProjectID ProjectName WorkItemID WorkItemType WorkItemName EstimateOptimistic EstimateProbable EstimatePessimistic RN SumTime
11 Data Group 94 Story Backlog Report with new logic 2 3 4 1 8
11 Data Group 94 Story Backlog Report with new logic 2 3 4 2 4
11 Data Group 94 Story Backlog Report with new logic 2 3 4 3 4
11 Data Group 94 Story Backlog Report with new logic 2 3 4 4 4
11 Data Group 94 Story Backlog Report with new logic 2 3 4 1 4
11 Data Group 94 Story Backlog Report with new logic 2 3 4 2 4
11 Data Group 94 Story Backlog Report with new logic 2 3 4 3 4
11 Data Group 94 Story Backlog Report with new logic 2 3 4 4 8
11 Data Group 94 Story Backlog Report with new logic 2 3 4 5 3
What I'm Looking for
ProjectID ProjectName WorkItemID WorkItemType WorkItemName EstimateOptimistic EstimateProbable EstimatePessimistic RN SumTime
11 Data Group 94 Story Backlog Report with new logic 2 3 4 1 8
11 Data Group 94 Story Backlog Report with new logic NULL NULL NULL 2 4
11 Data Group 94 Story Backlog Report with new logic NULL NULL NULL 3 4
11 Data Group 94 Story Backlog Report with new logic NULL NULL NULL 4 4
11 Data Group 94 Story Backlog Report with new logic 2 3 4 1 4
11 Data Group 94 Story Backlog Report with new logic NULL NULL NULL 2 4
11 Data Group 94 Story Backlog Report with new logic NULL NULL NULL 3 4
11 Data Group 94 Story Backlog Report with new logic NULL NULL NULL 4 8
11 Data Group 94 Story Backlog Report with new logic NULL NULL NULL 5 3
Hopefully that helps clarify what I'm trying for.
I suggest using a conditional SUM() and the ROW_NUMBER() function.
Let's say the query above outputs data like this:
Story, Task, TimeEntry
1234, 12, 120
1234, 12, 121
1234, 12, 134
1234, 13, 135
1234, 13, 120
1234, 13, 121
1234, 13, 134
1234, 14, 135
1234, 14, 120
1234, 14, 121
1234, 14, 134
1234, 14, 135
You could use this:
;WITH cte AS (SELECT *, ROW_NUMBER() OVER(PARTITION BY Story, Task ORDER BY TimeEntry) RN
FROM Table1
)
SELECT Story, Task, SUM(CASE WHEN RN = 1 THEN TimeEntry END) AS SumTime
FROM cte
GROUP BY Story, Task
Demo: SQL Fiddle
Each line will be numbered, starting at 1 for each combination of Story and Task, allowing you to use the condition of RN = 1 to avoid aggregating duplicate lines. Since you said the values repeat it doesn't matter what you put in the ORDER BY clause for your ROW_NUMBER().
Related
Not does not exclude query info
I have a really long query and I'm finding that my NOT is not excluding what's in parenthesis after the NOT. I saw Exclude and where not exists, but I'd have to re-select for that, and there's too many complicatedly joined tables in what I selected already, plus one table is very big and takes a long time to select what I have already, so I can't re-select because it will make the query take too long. How do I get this exclusion to work? INSERT INTO #UNeedingC(id, CASEID, firstname, lastname, userid, AGEOFNOTIFICATION, DATETIMEDECISIONMADE, DELEGATESYSTEM, Person_id, request_type_id, service_place_id, status_summary, externalUserId, subject, onDate, externalPersonId, externalSystemId) select distinct c.id ,uc.case_id ,t_case.FIRSTNAME as first ,t_case.LASTNAME as last ,t_case.user_id as userid ,CONVERT(VARCHAR, DATEDIFF(dd, SC.status_change_date, GETDATE())) + ' Day(s) ' + CONVERT(VARCHAR, DATEDIFF(hh, SC.status_change_date, GETDATE()) % 24) + ' Hour(s) ' as [AGE OF NOTIFICATION] ,SC.status_change_date AS [DATE TIME DECISION MADE] ,[ckoltp_sys].DBO.ckfn_GetStringLocaleValue(152,9,uc.delegate_system,50,0) AS [DELEGATESYSTEM] ,c.person_id ,uc.request_type_id ------ ,uc.service_place_id ,uc.status_summary ,eou.external_id ,c.tzix_id+' '+[ckoltp_sys].dbo.ckfn_GetStringLocaleValue(148,9,uc.status_summary,5,0)+' type' AS subject ,dateadd( hour,41,dateadd(day,0,datediff(d,0,sc.status_change_date)) ) AS onDate ,emd.externalId externalPersonId ,eou.system_id as externalSystemId --,u.disable from #tempC t_case with (NOLOCK) inner join dbo.org_case c with (nolock) ON t_case.Person_id=c.Person_id INNER JOIN dbo.org_2_case uc with (NOLOCK) ON uc.case_id=c.id inner JOIN dbo.ORG_LOS S WITH (NOLOCK) ON S.case_id = UC.case_id inner JOIN dbo.ORG_EXTENSION SC WITH (NOLOCK) ON SC.los_id= S.id inner join dbo.org_user u with (NOLOCK) on u.id=t_case.user_id inner join dbo.org_person op with (NOLOCK) on op.id=c.Person_id inner JOIN dbo.u_person_concept_value MC ON MC.CID = op.cid --this is the slow table inner join dbo.EXTERNAL_ORG_USER_DATA eou with (NOLOCK) ON eou.org_user_id = t_case.user_id inner join dbo.EXTERNAL_person_DATA emd with (NOLOCK) ON emd.CID = op.cid --op.id --? WHERE DATEDIFF(day, SC.status_change_date , GETDATE()) <= 2 AND u.disable <> 1 AND ( --(denied/approved) dbo.ckfn_GetStringLocaleValue(148,9,uc.status_summary,5,0) = 'Denied' OR (dbo.ckfn_GetStringLocaleValue(148,9,uc.status_summary,5,0) in( 'Fully Approved', 'Partially Approved')) ) AND ( ( ISNULL(uc.request_type_id,'') in( 12) AND DATEDIFF(month, SC.status_change_date , GETDATE()) <= 2 ) OR ( ISNULL(uc.request_type_id,'') in( 10,11) ) --OR --( -- --exclude this -- ( -- MC.concept_id = '501620' --general val1 (1000/1001) -- AND -- (C.ID in (select case_id from #CASES where str_value in ('1000','1001')) -- AND (uc.service_place_id = 31 OR uc.service_place_id = 32)) -- ) --not --) --or )--AND AND (t_case.firstname not like '%external%' and t_case.lastname not like '%case manager%') AND ( C.ID in (select case_id from #CASES where concept_id='501620')--MC.concept_id = '501620' ) --overall around AND (denied/approved)-- and DBO.ckfn_GetStringLocaleValue(152,9,uc.delegate_system,50,0) in ('AP','CA') AND NOT --this not is not working...this appears in query results ( --exclude these ( MC.concept_id = '501620' AND (C.ID in (select case_id from #CASES where str_value in ('1000','1001')) AND (uc.service_place_id = 31 OR uc.service_place_id = 32)) ) --not ) -- select * from #UNeedingC results show what is excluded: id caseid firstname lastname userid ageofNotification Datetimedecisionmade DelegateSys Person_id request_type_id service_place_id status_summary externalUserId subject onDate externalPersonId externalSystemId 000256200 256200 Sree Par 1234 0 Apr 5 CA 4270000 11 31 3 sparee 000256200 Fully Approved tested Ad 2021-04-06 17:00 363000 2 My question: do you know why the NOT is not working and how I can get this to exclude without another select? See "this not is not working" comment. I searched online but only found exclude and where not exists, which require another select, which I don't want.
I think I figured it out: "NOT acts on one condition. To negate two or more conditions, repeat the NOT for each condition," from not on two things. This seems to work: ... AND --exclude these ( MC.concept_id = '501620' --general val1 (1000/1001) AND (C.ID not in (select case_id from #CASES where str_value in ('1000','1001')) AND (uc.service_place_id not in ('31','32'))) ) --not
aggregating nested SQL statements to fewer columns
I am trying to aggregate my data and group it with respect to SKU's and the cluster ID associated with that SKU. My current output brings back roughly 40,000 rows (5 SKU's * 8,000 Stores) however I want just 35. My code: SELECT DISTINCT E.* FROM ALC_ITEM_SOURCE P RIGHT JOIN ( SELECT D.* ,SUM(L.ALLOCATED_QTY) AS TOTAL_ALLOCATED FROM ALC_ITEM_LOC L RIGHT JOIN ( SELECT C.* FROM STORE S, ( SELECT A.*, B.LOCATION AS STORE_NUMBER FROM FDT_MAP_CLUSTER_LOCATION B, ( SELECT DISTINCT SS.ALLOC_CLUSTER_ID, SS.ALLOC_CLUSTER_NAME, SS.SKU from fdt_maptool_sas_data ss WHERE SS.SKU IN (1099866, 1099896, 1000898, 1000960, 1000988 ) AND SS.ORDER_NO IS NOT NULL AND ALLOC_CLUSTER_NAME NOT LIKE '%DC Cluster%' GROUP BY SS.ALLOC_CLUSTER_ID, SS.ALLOC_CLUSTER_NAME, SS.WORKSHEET_ID, SS.SKU )A WHERE B.CLUSTER_ID = A.ALLOC_CLUSTER_ID AND B.LOCATION_TYPE = 'S' )C WHERE S.STORE = C.STORE_NUMBER AND S.STORE_CLOSE_DATE IS NULL AND S.DISTRICT NOT IN (997, 998, 999) AND S.STORE_OPEN_DATE <= SYSDATE )D ON L.ITEM_ID = D.SKU AND L.LOCATION_ID = D.STORE_NUMBER GROUP BY D.ALLOC_CLUSTER_ID, D.ALLOC_CLUSTER_NAME, D.SKU, D.STORE_NUMBER )E ON P.ITEM_ID = E.SKU AND P.SOURCE_TYPE <> 4 AND P.RELEASE_DATE > '01-FEB-2018' My desired result would contain: SKU Cluster_ID Total_allocated Count(stores) 1000989 1AA STORES 258 200 1000989 2A STORES 78 600 1000989 B STORES 36 500 1000989 C STORES 114 100 1000989 D STORES 144 1222 1000989 E STORES 168 600 1000989 F STORES 60 501 Which is taking a sum of total allocated per store per cluster ID. As you can see each SKU has a grade (AA-F), I would want to repeat this 5 times since I have 5 SKU's. Basically I am asking how can I aggregate my data up to look like the above table from the 40,000 rows it is now. Any help is appreciated!
Just to make your sql nicer and neat, you should avoid constructing joins in 'where' statement. Also I think you have nothing to do with ALC_ITEM_SOURCE table, since you did not use it practically. You may try this version, or at least start working on it: select SS.ALLOC_CLUSTER_ID,SS.ALLOC_CLUSTER_NAME,SS.SKU,SUM (L.ALLOCATED_QTY) as total_allocated,count(b.location) as store_number FROM fdt_maptool_sas_data ss inner join FDT_MAP_CLUSTER_LOCATION b on B.CLUSTER_ID =A.ALLOC_CLUSTER_ID AND B.LOCATION_TYPE = 'S' inner join store s on S.STORE = b.location AND S.STORE_CLOSE_DATE IS NULL AND S.DISTRICT NOT IN (997, 998, 999) AND S.STORE_OPEN_DATE <= SYSDATE left outer join ALC_ITEM_LOC L on L.ITEM_ID = ss.SKU AND L.LOCATION_ID = b.location WHERE SS.SKU IN (1099866, 1099896, 1000898, 1000960, 1000988) AND SS.ORDER_NO IS NOT NULL AND ALLOC_CLUSTER_NAME NOT LIKE '%DC Cluster%'
create an classification for months ordered
I'm trying to create an column in my query to show an ordered classification ( show 1, 2, 3 ( as in first, second, third ...)) relative to date... in my current query i have filtered data from the last 12 months ( as example, from 1-9-2016 to 31-8-2017) using DATEADD(mm; DATEDIFF(m; - 1; GETDATE()) - 12; 0) for the first date and DATEADD(s; - 1; DATEADD(mm; DATEDIFF(m; 0; GETDATE()) + 1; 0)) for the last day of the current month. And i also have two columns, one with the month and other with the year, both extracted from a document date column present in the data ( i'm using MONTH(dbo.Mov_Venda_Cab.dtmData) and YEAR(dbo.Mov_Venda_Cab.dtmData)). My goal is to have a column showing something like this : If the month is the first from the interval ( if is month 9 and year 2016 ) is has to show 1 , if is the second ( month 10 and year 2016) , show 2, all continuously until the current month ( that is 8 and year 2017) and showing 12. If the values where static i could do a simple case and would achieve what i wanted. My problem is that since when i get the data filtered by my current date and the 12 months behind, i don't manage to get the same result because i don't know exactly what i should do in the CASE expression. so that it could help my columns are : Item ; Qty ; Month ; Year ; dtmData ; orderedMonth ORIGINAL QUERY : SELECT DISTINCT DATEADD(mm, DATEDIFF(m, - 1, GETDATE()) - 12, 0) AS DATA_INI, DATEADD(s, - 1, DATEADD(mm, DATEDIFF(m, 0, GETDATE()) + 1, 0)) AS DATA_FIM, dbo.Mov_Venda_Lin.Id, MONTH(dbo.Mov_Venda_Cab.dtmData) AS Mes, YEAR(dbo.Mov_Venda_Cab.dtmData) AS Ano, dbo.Mov_Venda_Lin.fltValorMercadoriaSIVA * dbo.Mov_Venda_Cab.intSinal AS Mercadoria, dbo.Mov_Venda_Lin.fltValorLiquido * dbo.Mov_Venda_Cab.intSinal AS ValorLiquido, CASE WHEN tbl_tipos_documentos.bitconsideraqtdmapas = 1 THEN (Mov_Venda_Lin.fltQuantidade * mov_venda_cab.intsinal) ELSE 0 END AS Quantidade, dbo.Mov_Venda_Lin.strCodSeccao AS Seccao, dbo.Mov_Venda_Lin.strAbrevTpDoc AS TpDoc, dbo.Tbl_Tipos_Documentos.strDescricao AS DescTpDoc, dbo.Mov_Venda_Lin.intNumLinha AS Linha, dbo.Mov_Venda_Lin.strCodExercicio AS Exercicio, dbo.Mov_Venda_Cab.strAbrevMoeda AS Moeda, dbo.Mov_Venda_Cab.fltCambio AS Cambio, dbo.Mov_Venda_Lin.strCodArtigo AS Artigo, dbo.Tbl_Gce_Artigos.strDescricao AS DescArtigo, dbo.Mov_Venda_Lin.strCodClassMovStk AS MovStk, dbo.Tbl_ClassificacaoMovStk.strDescricao AS DescMovStk, CASE WHEN mov_venda_cab.inttpentidade = 0 THEN tbl_gce_tipos_entidade.strcodigo ELSE NULL END AS TpEntidade, CASE WHEN mov_venda_cab.inttpentidade = 0 THEN tbl_gce_tipos_entidade.strdescricao ELSE NULL END AS DescTpEntidade, CASE WHEN mov_venda_cab.intcodentidade <> 0 THEN mov_venda_cab.intcodentidade ELSE NULL END AS CodEntidade, CASE WHEN mov_venda_cab.inttpentidade = 0 AND mov_venda_cab.intcodentidade <> 0 THEN 'Cliente' WHEN mov_venda_cab.inttpentidade = 1 AND mov_venda_cab.intcodentidade <> 0 THEN 'Outro Devedor' ELSE NULL END AS TipoEntidade, CASE WHEN mov_venda_cab.inttpentidade = 0 THEN tbl_clientes.strnome ELSE tbl_outros_devedores.strnome END AS DescNome, dbo.Tbl_SubZonas.strAbrevZona AS Zona, dbo.Tbl_Zonas.strDescricao AS DescZona, dbo.Mov_Venda_Cab.strAbrevSubZona AS SubZona, dbo.Tbl_SubZonas.strDescricao AS DescSubZona, dbo.Mov_Venda_Cab.intCodVendedor AS Vendedor, dbo.Tbl_Gce_Vendedores.strNome AS DescNomeVend, dbo.Tbl_Gce_Artigos.strCodCategoria AS Categoria, dbo.Tbl_Gce_Categorias.strDescricao AS DescCategoria, dbo.Tbl_Gce_Artigos.strTpArtigo AS TpArtigo, dbo.Tbl_Gce_Tipos_Artigos.strDescricao AS DescTpArtigo, CAST(NULL AS VARCHAR(13)) AS CodFamiliaAgrup, CAST(NULL AS VARCHAR(35)) AS DescFamAgrup, CAST(NULL AS VARCHAR(13)) AS CodFamiliaRes, CAST(NULL AS VARCHAR(35)) AS DescFamRes, dbo.Mov_Venda_Cab.strForteAbrevMoeda AS abrevmoeda, dbo.Mov_Venda_Cab.fltForteCambio AS fortecambio FROM dbo.Mov_Venda_Lin WITH (NOLOCK) LEFT OUTER JOIN dbo.Mov_Venda_Cab WITH (NOLOCK) ON dbo.Mov_Venda_Lin.strCodSeccao = dbo.Mov_Venda_Cab.strCodSeccao AND dbo.Mov_Venda_Lin.strAbrevTpDoc = dbo.Mov_Venda_Cab.strAbrevTpDoc AND dbo.Mov_Venda_Lin.strCodExercicio = dbo.Mov_Venda_Cab.strCodExercicio AND dbo.Mov_Venda_Lin.intNumero = dbo.Mov_Venda_Cab.intNumero LEFT OUTER JOIN dbo.Tbl_Gce_Armazens WITH (NOLOCK) ON dbo.Mov_Venda_Lin.strCodArmazem = dbo.Tbl_Gce_Armazens.strCodigo LEFT OUTER JOIN dbo.Tbl_Gce_Artigos WITH (NOLOCK) ON dbo.Tbl_Gce_Artigos.strCodigo = dbo.Mov_Venda_Lin.strCodArtigo LEFT OUTER JOIN dbo.Tbl_Gce_ArtigosFamilias WITH (NOLOCK) ON dbo.Tbl_Gce_Artigos.strCodigo = dbo.Tbl_Gce_ArtigosFamilias.strCodArtigo LEFT OUTER JOIN dbo.Tbl_Gce_Familias WITH (NOLOCK) ON dbo.Tbl_Gce_ArtigosFamilias.strCodFamilia = dbo.Tbl_Gce_Familias.strCodigo LEFT OUTER JOIN dbo.Tbl_Gce_ArtigosReferencias WITH (NOLOCK) ON dbo.Tbl_Gce_Artigos.strCodigo = dbo.Tbl_Gce_ArtigosReferencias.strCodArtigo LEFT OUTER JOIN dbo.Tbl_Gce_Referencias WITH (NOLOCK) ON dbo.Tbl_Gce_ArtigosReferencias.strCodReferencia = dbo.Tbl_Gce_Referencias.strCodigo LEFT OUTER JOIN dbo.Tbl_Gce_Tipos_Artigos WITH (NOLOCK) ON dbo.Tbl_Gce_Artigos.strTpArtigo = dbo.Tbl_Gce_Tipos_Artigos.strCodigo LEFT OUTER JOIN dbo.Tbl_Clientes WITH (NOLOCK) ON dbo.Mov_Venda_Cab.intCodEntidade = dbo.Tbl_Clientes.intCodigo LEFT OUTER JOIN dbo.Tbl_Direccoes WITH (NOLOCK) ON dbo.Mov_Venda_Cab.intCodEntidade = dbo.Tbl_Direccoes.intCodigo AND dbo.Mov_Venda_Cab.intDireccao = dbo.Tbl_Direccoes.intNumero AND dbo.Mov_Venda_Cab.intTpEntidade = dbo.Tbl_Direccoes.intTp_Entidade LEFT OUTER JOIN dbo.Tbl_Outros_Devedores WITH (NOLOCK) ON dbo.Mov_Venda_Cab.intCodEntidade = dbo.Tbl_Outros_Devedores.intCodigo LEFT OUTER JOIN dbo.Tbl_Gce_Vendedores WITH (NOLOCK) ON dbo.Mov_Venda_Cab.intCodVendedor = dbo.Tbl_Gce_Vendedores.intCodigo LEFT OUTER JOIN dbo.Tbl_Tipos_Documentos WITH (NOLOCK) ON dbo.Mov_Venda_Cab.strAbrevTpDoc = dbo.Tbl_Tipos_Documentos.strAbreviatura LEFT OUTER JOIN dbo.Tbl_SubZonas WITH (NOLOCK) ON dbo.Mov_Venda_Cab.strAbrevSubZona = dbo.Tbl_SubZonas.strAbreviatura LEFT OUTER JOIN dbo.Tbl_Zonas WITH (NOLOCK) ON dbo.Tbl_SubZonas.strAbrevZona = dbo.Tbl_Zonas.strAbreviatura LEFT OUTER JOIN dbo.Tbl_Gce_Categorias WITH (NOLOCK) ON dbo.Tbl_Gce_Artigos.strCodCategoria = dbo.Tbl_Gce_Categorias.strCodigo LEFT OUTER JOIN dbo.Tbl_Gce_Seccoes WITH (NOLOCK) ON dbo.Mov_Venda_Cab.strCodSeccao = dbo.Tbl_Gce_Seccoes.strCodigo LEFT OUTER JOIN dbo.Tbl_Gce_Tipos_Entidade WITH (NOLOCK) ON dbo.Tbl_Clientes.strTpEntidade = dbo.Tbl_Gce_Tipos_Entidade.strCodigo LEFT OUTER JOIN dbo.Tbl_ClassificacaoMovStk WITH (NOLOCK) ON dbo.Mov_Venda_Lin.strCodClassMovStk = dbo.Tbl_ClassificacaoMovStk.strCodigo WHERE (dbo.Mov_Venda_Cab.intTpEntidade = 0 OR dbo.Mov_Venda_Cab.intTpEntidade IS NULL) AND (dbo.Mov_Venda_Cab.strAbrevTpDoc IN ('CRFCX', 'FACIV', 'FACTC', 'FCTA', 'LANIV', 'LOFX', 'LONC', 'LXANI', 'NCFCX', 'NFACC', 'NFACE', 'NFACM', 'NFACT', 'NNCRC', 'NNCRE', 'NNCRM', 'NNDEB', 'NNDEC', 'NNDEV', 'NVDIC', 'NVDIN', 'XLACC', 'XLACD')) AND (dbo.Mov_Venda_Cab.strCodSeccao IN ('1', 'ENCT1', 'ENCT2', 'ENCT3', 'ENCT4', 'ENCT5', 'ENCT6')) AND (dbo.Mov_Venda_Cab.dtmData > DATEADD(mm, DATEDIFF(m, - 1, GETDATE()) - 12, 0)) AND (dbo.Mov_Venda_Cab.dtmData <= DATEADD(s, - 1, DATEADD(mm, DATEDIFF(m, 0, GETDATE()) + 1, 0))) AND (dbo.Mov_Venda_Lin.intTpLinha > 2) AND (dbo.Mov_Venda_Cab.bitAnulado = 0) AND (dbo.Mov_Venda_Cab.bitConvertido = 0)
Luckily there's a much less complicated method than using a bunch of CASE statements. You can use the ROW_NUMBER function. First, don't split your dates into month and year. Just use Getdate() to calculate your desired range and compare your source dates to that. Then you add the ROW_NUMBER to get your ordering output: SELECT * ,ordered_output = (ROW_NUMBER()OVER(PARTITION BY grouping_field ORDER BY cast(dtmData as datetime) ASC)) FROM Mov_Venda_Cab WHERE cast(dtmData as datetime) >= getdate() - 365 This example assumes your have some ID field or similar on which your want to group your output, represented by grouping_field in the example. Your results would look like: grouping_field dtmData ordered_output 1 8/1/2017 1 1 8/2/2017 2 1 8/3/2017 3 2 8/1/2017 1 2 8/2/2017 2 2 8/3/2017 3 If you don't want to group your output, just ordering everything by the date, you can omit the PARTITION BY grouping_field text. You'd get instead something like: dtmData ordered_output 8/1/2017 1 8/2/2017 2 8/3/2017 3 8/4/2017 4 8/5/2017 5 8/6/2017 6 EDIT: Asker clarified that all records with the same month should get the same ordered output. To do that you first need to assign each month/year combo a rank and rejoin that to the main table using two layers of subqueries: SELECT b.*, c.month_rank from Mov_Venda_Cab as b inner join (select mnt, yr, ROW_NUMBER() OVER(ORDER BY A.yr, A.mnt) AS month_rank from ( SELECT DISTINCT MONTH(dtmData) as mnt , YEAR(dtmData) as yr from Mov_Venda_Cab WHERE cast(dtmData as datetime) >= getdate() - 365 ) as a ) as c on MONTH(b.dtmData) = c.mnt and YEAR(b.dtmData) = c.yr
Combining multiple rows in TSQL query
I have a table with data like this Road Item Response added_on 1 82 Yes 7/11/16 1 83 Yes 7/11/16 1 84 Yes 7/11/16 2 82 Yes 8/11/16 2 83 No 8/11/16 2 85 Yes 8/11/16 This reflects an assessment of a road where 'item' is things being assessed. Some items will always be done during an assessment (82, 83) where others are optional (84, 85). I want to return something that combines all of the assessment results for a road/date, returning null if that item was not assessed. And also only returning last month's results. For example Road 82 83 84 85 added_on 1 Yes Yes Yes 7/11/16 2 Yes No Yes 8/11/16 I have tried a multiple self joins like this but it's returning nothing. FROM assess AS A JOIN assess AS B ON A.road = B.road AND a.added_on = B.added on JOIN assess AS C ON A.road = C.road AND a.added_on = C.added on JOIN assess AS D ON A.road = D.road AND a.added_on = D.added on WHERE A.item = '81' AND B.item = '82' AND (C.item = '83' OR C.item IS NULL) AND (D.item = '84' OR D.item IS NULL) AND datepart(month,A.added_on) = datepart(month,getdate()) -1 To clarify, -no road is assessed more than once a day -each item is only assessed once, and sometimes is NULL i.e. not applicable -multiple roads are assessed each day -this table has other assessments but we aren't worried about those. Any ideas? Using SQL server 2008. Thanks.
Assuming you need to go Dynamic Declare #SQL varchar(max) Select #SQL = Stuff((Select Distinct ',' + QuoteName(Item) From YourTable Order By 1 For XML Path('')),1,1,'') Select #SQL = 'Select [Road],' + #SQL + ',[added_on] From YourTable Pivot (max(Response) For Item in (' + #SQL + ') ) p' Exec(#SQL); Returns EDIT - The SQL Generated is as follows. (just in case you can't go dynamic) Select [Road],[82],[83],[84],[85],[added_on] From YourTable Pivot (max(Response) For Item in ([82],[83],[84],[85]) ) p
Another way of achieving this is less elegant, but uses basic operations if you don't want to use pivot. Load up test data create table #assess ( road int, item varchar(10), response varchar(3), added_on date ) insert #assess( road, item, response, added_on ) values (1, '82', 'Yes', '2016-07-11' ) , (1, '83', 'Yes', '2016-07-11' ) , (1, '84', 'Yes', '2016-07-11' ) , (2, '82', 'Yes', '2016-08-11' ) , (2, '83', 'No', '2016-08-11' ) , (2, '85', 'Yes', '2016-08-11' ) Process the data -- Get every possible `item` select distinct item into #items from #assess -- Ensure every road/added_on combination has all possible values of `item` -- If the combination does not exist in original data, leave `response` as blank select road, added_on, i.item, cast('' as varchar(3)) as response into #assess2 from #items as i cross join #assess AS A group by road, added_on, i.item update a set response = b.response from #assess2 a inner join #assess b on A.road = B.road AND a.added_on = B.added_on AND a.item = b.item -- Join table to itself 4 times - inner join if `item` must exist or left join if `item` is optional select a.road, a.added_on, a.response as '82', b.response as '83', c.response as '84', d.response as '85' FROM #assess2 AS A INNER JOIN #assess2 AS B ON A.road = B.road AND a.added_on = B.added_on LEFT JOIN #assess2 AS C ON A.road = C.road AND a.added_on = C.added_on LEFT JOIN #assess2 AS D ON A.road = D.road AND a.added_on = D.added_on WHERE A.item = '82' AND B.item = '83' AND (C.item = '84' OR C.item IS NULL) AND (D.item = '85' OR D.item IS NULL) --AND datepart(month,A.added_on) = datepart(month,getdate()) -1 The resultset is: road added_on 82 83 84 85 1 2016-07-11 Yes Yes Yes 2 2016-08-11 Yes No Yes
I would do this using conditional aggregation: select road, max(case when item = 82 then response end) as response_82, max(case when item = 83 then response end) as response_83, max(case when item = 84 then response end) as response_84, max(case when item = 85 then response end) as response_85, added_on from t group by road, added_on order by road; For the month component, you can add a where clause. One method is: where year(date_added) * 12 + month(date_added) = year(getdate())*12 + month(getdate()) - 1 Or, you can use logic like this: where date_added < dateadd(day, 1 - day(getdate()), cast(getdate() as date)) and date_added >= dateadd(month, -1, dateadd(day, 1 - day(getdate()), cast(getdate() as date))) The second looks more complicated but it is sargable, meaning that an index on date_added can be used (if one is available).
Generate Zeroes when no rows where selected
Good Day Every one i have this code SELECT 'Expired Item -'+ DateName(mm,DATEADD(MM,4,AE.LOAN)) as [Month] ,COUNT(ISNULL(PIT.ID,0))'COUNT' ,SUM(ISNULL(PIT.KGRAM,0))'GRAMS' ,SUM(ISNULL(PH.AMOUNT,0))'PRINCIPAL' FROM #AllExpired AE INNER JOIN Transactions.ITEM PIT ON AE.MAINID=PIT.MAINID INNER JOIN Transactions.HISTO PH ON AE.MAINID=PH.MAINID GROUP BY DATENAME(MM,(DATEADD(MM,4,AE.LOAN))) UNION ALL /*SELECT EXPIRED AFTER 5 MONTHS*/ SELECT 'Expired Item -'+ DateName(mm,DATEADD(MM,5,AE.LOAN)) as [Month] ,COUNT(ISNULL(PIT.ID,0))'COUNT' ,SUM(ISNULL(PIT.KGRAM,0))'GRAMS' ,SUM(ISNULL(PH.AMOUNT,0))'PRINCIPAL' FROM #ExpAfterFiveMonths E5 INNER JOIN Transactions.ITEM PIT ON E5.MAINID=PIT.MAINID INNER JOIN Transactions.HISTO PH ON E5.MAINID=PH.MAINID INNER JOIN #AllExpired AE ON AE.MAINID=E5.MAINID GROUP BY DATENAME(MM,(DATEADD(MM,5,AE.LOAN))) UNION ALL /*SELECT EXPIRED AFTER 6 MONTHS*/ SELECT 'Expired Item -'+ DateName(mm,DATEADD(MM,6,AE.LOAN)) as [Month] ,COUNT(ISNULL(PIT.ID,0))'COUNT' ,SUM(ISNULL(PIT.KGRAM,0))'GRAMS' ,SUM(ISNULL(PH.AMOUNT,0))'PRINCIPAL' FROM #ExpAfterSixMonths E6 INNER JOIN Transactions.ITEM PIT ON E6.MAINID=PIT.MAINID INNER JOIN Transactions.HISTO PH ON E6.MAINID=PH.MAINID INNER JOIN #AllExpired AE ON AE.MAINID=E6.MAINID GROUP BY DATENAME(MM,(DATEADD(MM,6,AE.LOAN))) and it works fine, the problem is that when the Select statements retrieved no rows they become empty instead of replacing zeroes instead of Generating the word month with 0 0 0 it just pops out empty in which i dont like,, can you help me achive that? the result should be something like this ------------------------------------------------------------------ MONTH | Count | Grams | Principal | October |123123 | 123123 | 123123213 | November | 0 | 0 | 0 | // this should appear if no rows where selected instead of blank here is my code to generate the items inside temptables SELECT TE.MAINID ,TE.EXPIRY ,TE.LOAN ,PM.STORAGE into #AllExpiredAfterFiveAndSix FROM #ExpiredAfterFiveandSixMon TE inner join Transactions.TABLEMAIN PM on TE.MAINID = PM.MAINID inner join #AllExpired E4 on E4.MAINID=TE.MAINID WHERE ((cast(TE.EXPIRY as date) < cast(TE.newloandate as date)) OR(TE.NewLoanDate is null and ((cast(TE.EXPIRY as date) < cast(PM.DATERED as date)) or PM.STATUS = 7 or PM.STATUS = 5)) ) AND (PM.STORAGE BETWEEN 3 AND 14 OR PM.STORAGE=17) /*EXPIRED AFTER 5 MONTHS*/ select AE.MAINID ,AE.LOAN ,AE.STORAGE ,ae.EXPIRY into #ExpAfterFiveMonths from #AllExpiredAfterFiveAndSix AE inner join #AllExpired E4 on E4.MAINID=AE.MAINID where MONTH(AE.EXPIRY)= MONTH(dateadd(mm,1,E4.EXPIRY)) /*EXPIRED AFTER 6 MONTHS*/ select AE.MAINID ,AE.LOAN ,AE.STORAGE ,ae.EXPIRY into #ExpAfterSixMonths from #AllExpiredAfterFiveAndSix AE inner join #AllExpired E4 on E4.MAINID=AE.MAINID where MONTH(AE.EXPIRY)= MONTH(dateadd(mm,2,E4.EXPIRY)) CREATE NONCLUSTERED INDEX IDX_ExpAfterFiveMonths ON #ExpAfterFiveMonths(MAINID) CREATE NONCLUSTERED INDEX IDX_ExpAfterSixMonths ON #ExpAfterSixMonths(MAINID) i hope you can help me because im just a starter in sql i have tried using is NULL as what you have seen above but i do not know if i implement it correctly Hoping for your Kindness and consideration thank you :) ****EDIT** The temp tables contains no values to start with, i just want it to output 0 instead of blank.
Edited: Added a months table to handle empty temp tables. Change inner joins to left joins. DECLARE #months TABLE (ReportMonth VARCHAR(20) NOT NULL) INSERT INTO #months VALUES ('January'),('February'),('March'),('April'), ('May'),('June'),('July'),('August'), ('September'),('October'),('November'),('December') SELECT 'Expired Item -'+ COALESCE(DateName(mm,DATEADD(MM,4,AE.fld_LoanDate)), M.ReportMonth) as [Month] ,COUNT(ISNULL(PIT.fld_PawnItemID,0))'COUNT' ,SUM(ISNULL(PIT.fld_KaratGram,0))'GRAMS' ,SUM(ISNULL(PH.fld_PrincipalAmt,0))'PRINCIPAL' FROM #months M LEFT JOIN #AllExpired AE ON M.ReportMonth = DateName(mm,DATEADD(MM,4,AE.fld_LoanDate)) LEFT JOIN Transactions.tbl_PawnItem PIT ON AE.fld_PawnMainID=PIT.fld_PawnMainID LEFT JOIN Transactions.tbl_PawnHisto PH ON AE.fld_PawnMainID=PH.fld_PawnMainID GROUP BY M.ReportMonth UNION ALL /*SELECT EXPIRED AFTER 5 MONTHS*/ SELECT 'Expired Item -'+ 'Expired Item -'+ COALESCE(DateName(mm,DATEADD(MM,5,AE.fld_LoanDate)), M.ReportMonth) as [Month] ,COUNT(ISNULL(PIT.fld_PawnItemID,0))'COUNT' ,SUM(ISNULL(PIT.fld_KaratGram,0))'GRAMS' ,SUM(ISNULL(PH.fld_PrincipalAmt,0))'PRINCIPAL' FROM #months M LEFT JOIN #AllExpired AE ON M.ReportMonth = DateName(mm,DATEADD(MM,5,AE.fld_LoanDate)) LEFT JOIN #ExpAfterFiveMonths E5 ON AE.fld_PawnMainID=E5.fld_PawnMainID LEFT JOIN Transactions.tbl_PawnItem PIT ON E5.fld_PawnMainID=PIT.fld_PawnMainID LEFT JOIN Transactions.tbl_PawnHisto PH ON E5.fld_PawnMainID=PH.fld_PawnMainID GROUP BY M.ReportMonth UNION ALL /*SELECT EXPIRED AFTER 6 MONTHS*/ SELECT 'Expired Item -'+ COALESCE(DateName(mm,DATEADD(MM,6,AE.fld_LoanDate)), M.ReportMonth) as [Month] ,COUNT(ISNULL(PIT.fld_PawnItemID,0))'COUNT' ,SUM(ISNULL(PIT.fld_KaratGram,0))'GRAMS' ,SUM(ISNULL(PH.fld_PrincipalAmt,0))'PRINCIPAL' FROM #months M LEFT JOIN #AllExpired AE ON M.ReportMonth = DateName(mm,DATEADD(MM,6,AE.fld_LoanDate)) LEFT JOIN #ExpAfterSixMonths E6 ON AE.fld_PawnMainID=E6.fld_PawnMainID LEFT JOIN Transactions.tbl_PawnItem PIT ON E6.fld_PawnMainID=PIT.fld_PawnMainID LEFT JOIN Transactions.tbl_PawnHisto PH ON E6.fld_PawnMainID=PH.fld_PawnMainID GROUP BY M.ReportMonth
Try this in your select SELECT (CASE WHEN (AE.fld_LoanDate IS null) THEN 0 ELSE AE.fld_LoanDate END) as fld_LoanDate
Though both answers do what the questioner wanted, I though I would suggest 'where LoanDate in (range)', 'group by', along with left join, and a date range. So, you have tables like this: CREATE TABLE tPawnItem ( fPawnItemID int auto_increment primary key, fDescription varchar(30), fKaratGram float ); CREATE TABLE tPawnHisto ( fPawnMainID int primary key, fPrincipalAmt int, fRedeemed date ); create table tExp ( fPawnMainID int primary key, fLoanDate date ); This is proximately what I'm suggesting (I don't have my laptop, so no mysql right now), SELECT 'Expired Item -'+ DATENAME(MM,tExp.fLoanDate) as [Month] ,COUNT(ISNULL(tPawnItem.fPawnItemID,0))'COUNT' ,SUM(ISNULL(tPawnItem.fKaratGram,0))'GRAMS' ,SUM(ISNULL(tPawnHisto.fPrincipalAmt,0))'PRINCIPAL' FROM tExp INNER JOIN tPawnItem ON tExp.fPawnMainID=tPawnItem.fPawnMainID INNER JOIN tPawnHisto ON tExp.fPawnMainID=tPawnHisto.fPawnMainID WHERE t.Exp.fLoanDate in ( DATENAME(MM,DATEADD(MM,4,tExp.fLoanDate)), DATENAME(MM,DATEADD(MM,5,tExp.fLoanDate)), DATENAME(MM,DATEADD(MM,6,tExp.fLoanDate)), DATENAME(MM,DATEADD(MM,7,tExp.fLoanDate)) ) GROUP BY DATENAME(MM,tExp.fLoanDate);