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);