How to minimize my big query for showing counts using SQL - sql

I am taking counts from CTE but common is Status(working,pening) and Divisions
but my query is becoming big because left join is same but just status and division are different. I have wrote 10 left join count but by passing status and divisions.
Below is my whole sql query
declare #createdBy int=79
;with cte as (
select max(w.WorkingNo)WorkingNo
from
working w
join workingdealhistory wd on wd.WorkHistoryId=w.workingNo and
w.status IN ('WORKING','PENDING') and w.mhlId>0 and w.IsActive=1
join TreasureTrove t on t.CandidateId=w.CandidateId and t.DepartmentId=2
group by w.CandidateId,w.status
)
select distinct m.potentialHospitalNo
,m.hospital
,ph.clientname
,cdiwr.working cdiworking
,cdipn.pending cdipending
,himwr.working himworking
,himpn.pending himpending
,cmurwr.working cmurworking
,cmurpn.pending cmurpending
,odmwr.working odmworking
,odmpn.pending odmpending
,traumawr.working traumaworking
,traumapn.pending traumapending
,ph.ClientId
from PotentialHospitlMaster m (NOLOCK)
Inner JOIN HospitalStatus HS (NOLOCK) On m.potentialHospitalNo=HS.ClientId
inner join potentialhospital ph on ph.potentialhospitalno=m.potentialhospitalno
--this is status='working' and division='CDI'
LEFT join(select COUNT(w.WorkingNo)working, MHLId from cte c inner join
working w on w.WorkingNo=c.WorkingNo
inner join WorkingDealHistory WH on w.WorkingNo=WH.WorkHistoryId
inner join potentialhospital phs on phs.potentialHospitalNo=w.MHLId where w.Status='working' and wh.Division='CDI' group by w.MHLId) as cdiwr on cdiwr.MHLId=ph.potentialHospitalNo
--this is status='pending' and division='CDI'
LEFT join(select COUNT(w.WorkingNo)pending, MHLId from cte c inner join
working w on w.WorkingNo=c.WorkingNo
inner join WorkingDealHistory WH on w.WorkingNo=WH.WorkHistoryId
inner join potentialhospital phs on phs.potentialHospitalNo=w.MHLId where w.Status='pending' and wh.Division='CDI' group by w.MHLId) as cdipn on cdipn.MHLId=ph.potentialHospitalNo
--this is status='working' and division='HIM'
LEFT join(select COUNT(w.WorkingNo)working, MHLId from cte c inner join
working w on w.WorkingNo=c.WorkingNo
inner join WorkingDealHistory WH on w.WorkingNo=WH.WorkHistoryId
inner join potentialhospital phs on phs.potentialHospitalNo=w.MHLId where w.Status='working' and wh.Division='HIM' group by w.MHLId) as himwr on himwr.MHLId=ph.potentialHospitalNo
--this is status='pending' and division='HIM'
LEFT join(select COUNT(w.WorkingNo)pending, MHLId from cte c inner join
working w on w.WorkingNo=c.WorkingNo
inner join WorkingDealHistory WH on w.WorkingNo=WH.WorkHistoryId
inner join potentialhospital phs on phs.potentialHospitalNo=w.MHLId where w.Status='pending' and wh.Division='HIM' group by w.MHLId) as himpn on himpn.MHLId=ph.potentialHospitalNo
--this is status='working' and division='CMUR'
LEFT join(select COUNT(w.WorkingNo)working, MHLId from cte c inner join
working w on w.WorkingNo=c.WorkingNo
inner join WorkingDealHistory WH on w.WorkingNo=WH.WorkHistoryId
inner join potentialhospital phs on phs.potentialHospitalNo=w.MHLId where w.Status='working' and wh.Division='CMUR' group by w.MHLId) as cmurwr on cmurwr.MHLId=ph.potentialHospitalNo
--this is status='pending' and division='CMUR'
LEFT join(select COUNT(w.WorkingNo)pending, MHLId from cte c inner join
working w on w.WorkingNo=c.WorkingNo
inner join WorkingDealHistory WH on w.WorkingNo=WH.WorkHistoryId
inner join potentialhospital phs on phs.potentialHospitalNo=w.MHLId where w.Status='pending' and wh.Division='CMUR' group by w.MHLId) as cmurpn on cmurpn.MHLId=ph.potentialHospitalNo
--this is status='working' and division='ODM'
LEFT join(select COUNT(w.WorkingNo)working, MHLId from cte c inner join
working w on w.WorkingNo=c.WorkingNo
inner join WorkingDealHistory WH on w.WorkingNo=WH.WorkHistoryId
inner join potentialhospital phs on phs.potentialHospitalNo=w.MHLId where w.Status='working' and wh.Division='ODM' group by w.MHLId) as odmwr on odmwr.MHLId=ph.potentialHospitalNo
--this is status='pending' and division='ODM'
LEFT join(select COUNT(w.WorkingNo)pending, MHLId from cte c inner join
working w on w.WorkingNo=c.WorkingNo
inner join WorkingDealHistory WH on w.WorkingNo=WH.WorkHistoryId
inner join potentialhospital phs on phs.potentialHospitalNo=w.MHLId where w.Status='pending' and wh.Division='ODM' group by w.MHLId) as odmpn on odmpn.MHLId=ph.potentialHospitalNo
--this is status='working' and division='Trauma'
LEFT join(select COUNT(w.WorkingNo)working, MHLId from cte c inner join
working w on w.WorkingNo=c.WorkingNo
inner join WorkingDealHistory WH on w.WorkingNo=WH.WorkHistoryId
inner join potentialhospital phs on phs.potentialHospitalNo=w.MHLId where w.Status='working' and wh.Division='Trauma' group by w.MHLId) as traumawr on traumawr.MHLId=ph.potentialHospitalNo
--this is status='pending' and division='Trauma'
LEFT join(select COUNT(w.WorkingNo)pending, MHLId from cte c inner join
working w on w.WorkingNo=c.WorkingNo
inner join WorkingDealHistory WH on w.WorkingNo=WH.WorkHistoryId
inner join potentialhospital phs on phs.potentialHospitalNo=w.MHLId where w.Status='pending' and wh.Division='Trauma' group by w.MHLId) as traumapn on traumapn.MHLId=ph.potentialHospitalNo
where m.IsActive=1 and HS.UpdatedStatus='MSA Sent' and HS.CreatedBy=#createdBy
Is there anything which we can minimize query by using group by or anything.

I've taken a bit of a stab at your schema, and I think you could do it with something like:
DECLARE #createdBy INT = 79;
WITH cte AS
(
SELECT w.CandidateId, w.status, WorkingNo = MAX(w.WorkingNo)
FROM working AS w
JOIN workingdealhistory AS wd
ON wd.WorkHistoryId = w.workingNo
AND w.status IN ('WORKING', 'PENDING')
AND w.mhlId > 0
AND w.IsActive = 1
JOIN TreasureTrove AS t
ON t.CandidateId = w.CandidateId
AND t.DepartmentId = 2
GROUP BY
w.CandidateId, w.status;
)
SELECT DISTINCT
m.potentialHospitalNo,
m.hospital,
ph.clientname,
cnt.CDIworking,
cnt.CDIPending,
cnt.HIMworking,
cnt.HIMPending,
cnt.CMURworking,
cnt.CMURPending,
cnt.ODMworking,
cnt.ODMPending,
cnt.Traumaworking,
cnt.TraumaPending
ph.ClientId
FROM PotentialHospitlMaster AS m
INNER JOIN HospitalStatus AS HS
ON m.potentialHospitalNo = HS.ClientId
INNER JOIN potentialhospital AS ph
ON ph.potentialhospitalno = m.potentialhospitalno
LEFT JOIN
(
SELECT w.MHLId,
CDIworking = COUNT(CASE WHEN w.Status = 'working' AND wh.Division = 'CDI' THEN w.WorkingNo END),
CDIPending = COUNT(CASE WHEN w.Status = 'pending' AND wh.Division = 'CDI' THEN w.WorkingNo END),
HIMworking = COUNT(CASE WHEN w.Status = 'working' AND wh.Division = 'HIM' THEN w.WorkingNo END),
HIMPending = COUNT(CASE WHEN w.Status = 'pending' AND wh.Division = 'HIM' THEN w.WorkingNo END),
CMURworking = COUNT(CASE WHEN w.Status = 'working' AND wh.Division = 'CMUR' THEN w.WorkingNo END),
CMURPending = COUNT(CASE WHEN w.Status = 'pending' AND wh.Division = 'CMUR' THEN w.WorkingNo END),
ODMworking = COUNT(CASE WHEN w.Status = 'working' AND wh.Division = 'ODM' THEN w.WorkingNo END),
ODMPending = COUNT(CASE WHEN w.Status = 'pending' AND wh.Division = 'ODM' THEN w.WorkingNo END),
Traumaworking = COUNT(CASE WHEN w.Status = 'working' AND wh.Division = 'Trauma' THEN w.WorkingNo END),
TraumaPending = COUNT(CASE WHEN w.Status = 'pending' AND wh.Division = 'Trauma' THEN w.WorkingNo END)
FROM working AS w
INNER JOIN WorkingDealHistory AS wh
ON w.WorkingNo = wh.WorkHistoryId
INNER JOIN cte AS c
ON c.CandidateId = w.CandidateId
AND c.status = w.status
AND c.WorkingNo = w.WorkingNo
GROUP BY
w.MHLId
) AS cnt
ON cnt.MHLId = ph.potentialHospitalNo
WHERE m.IsActive = 1
AND HS.UpdatedStatus = 'MSA Sent'
AND HS.CreatedBy = #createdBy;
N.B. I've removed NOLOCK as putting this everywhere is a bad habit to kick. Also, I am deeply suspicious of most queries that use DISTINCT across a large number of columns like this. More often than not the duplicates are a symptom of an error with the query, and DISTINCT is just a nasty plaster trying to cover up the real issue. You should work out where duplicates are coming from and look to remove either early or at least in a deterministic fashion.

Related

Filtering by values

I wrote a query a few days ago to determine whether a software is installed on a computer or not but I'm having troubles with filtering it showing only the "NO" values.
Would appreciate any help, thanks
Select Distinct Top 1000000 tblAssets.AssetName,
tsysOS.OSname,
Case
When soft01.AssetID Is Null Then 'NO'
Else 'YES'
End As Avecto,
Case
When soft02.AssetID Is Null Then 'NO'
Else 'YES'
End As CrowdStrike,
Case
When soft03.AssetID Is Null Then 'NO'
Else 'YES'
End As Cortex,
tblAssets.Firstseen,
tblAssets.Lastseen
From tblAssets
Left Join tblAssetCustom On tblAssets.AssetID = tblAssetCustom.AssetID
Left Join tsysOS On tsysOS.OScode = tblAssets.OScode
Left Join (Select tblSoftware.AssetID
From tblSoftware
Inner Join tblSoftwareUni On tblSoftwareUni.SoftID = tblSoftware.softID
Where tblSoftwareUni.softwareName Like '%Avecto%') As soft01 On
soft01.AssetID = tblAssets.AssetID
Left Join (Select tblSoftware.AssetID
From tblSoftware
Inner Join tblSoftwareUni On tblSoftwareUni.SoftID = tblSoftware.softID
Where tblSoftwareUni.softwareName Like '%CrowdStrike%') As soft02 On
soft02.AssetID = tblAssets.AssetID
Left Join (Select tblSoftware.AssetID
From tblSoftware
Inner Join tblSoftwareUni On tblSoftwareUni.SoftID = tblSoftware.softID
Where (tblSoftwareUni.softwareName Like '%Cortex%' Or
tblSoftwareUni.softwareName Like '%XDR%')) As soft03 On
soft03.AssetID = tblAssets.AssetID
Where tsysOS.OSname Like '%Win 20%'
Order By tblAssets.AssetName

Counting all records from inner-join

I have 4 tables that has aantal ( count ) and each tables shows normal numbers or numbers with - before (example: -20) now I need to count all that records. but I don't know how I can fix that.
Sorry I am a noob in sql.
this is my code
The problem that i facing to is tha all records from the different tables that has column aantal not counting in total.
example:
CSSDKMagento_10_Plankvoorraad returns 10
CSSDKMagento_20_GeenAllocatieWelFiat returns -3 and -2
CSSDKMagento_30_AllocatieVoorraad returns 5
CSSDKMagento_50_AllocatieBestellingBinnen returns -1 and -1
That means that i get on return from Voorraad is 8.
I tried count(*) but that is not the solution. with best way I can do it?
SELECT
i.ItemCode,
g.warehouse,
SUM(g.aantal) AS Voorraad,
MAX(CASE
WHEN g.transtype = 'N' THEN g.sysmodified
ELSE NULL
END) AS LastDate
FROM dbo.CSSDKMagento_10_Plankvoorraad AS g
INNER JOIN dbo.Items AS i
ON (g.artcode = i.ItemCode)
INNER JOIN dbo.CSSDKMagento_20_GeenAllocatieWelFiat AS a
ON (a.artcode = i.ItemCode)
INNER JOIN dbo.CSSDKMagento_30_AllocatieVoorraad AS v
ON (v.artcode = i.ItemCode)
INNER JOIN dbo.CSSDKMagento_50_AllocatieBestellingBinnen AS b
ON (b.artcode = i.ItemCode)
WHERE
i.itemcode = 'TEST'
GROUP BY i.itemcode,
g.warehouse;
Try this
SELECT
i.ItemCode,
g.warehouse,
SUM(g.aantal)+SUM(a.aantal)+SUM(v.aantal)+SUM(b.aantal) AS Voorraad,
MAX(CASE
WHEN g.transtype = 'N' THEN g.sysmodified
ELSE NULL
END) AS LastDate
FROM dbo.CSSDKMagento_10_Plankvoorraad AS g
INNER JOIN dbo.Items AS i
ON (g.artcode = i.ItemCode)
INNER JOIN dbo.CSSDKMagento_20_GeenAllocatieWelFiat AS a
ON (a.artcode = i.ItemCode)
INNER JOIN dbo.CSSDKMagento_30_AllocatieVoorraad AS v
ON (v.artcode = i.ItemCode)
INNER JOIN dbo.CSSDKMagento_50_AllocatieBestellingBinnen AS b
ON (b.artcode = i.ItemCode)
WHERE
i.itemcode = 'TEST'
GROUP BY i.itemcode,
g.warehouse;
Edited:
SELECT SUM(Voorraad) FROM (
SELECT
i.ItemCode,
g.warehouse,
g.aantal AS Voorraad,
MAX(CASE
WHEN g.transtype = 'N' THEN g.sysmodified
ELSE NULL
END) AS LastDate
FROM dbo.CSSDKMagento_10_Plankvoorraad AS g
INNER JOIN dbo.Items AS i
ON (g.artcode = i.ItemCode)
INNER JOIN dbo.CSSDKMagento_20_GeenAllocatieWelFiat AS a
ON (a.artcode = i.ItemCode)
INNER JOIN dbo.CSSDKMagento_30_AllocatieVoorraad AS v
ON (v.artcode = i.ItemCode)
INNER JOIN dbo.CSSDKMagento_50_AllocatieBestellingBinnen AS b
ON (b.artcode = i.ItemCode)
WHERE
i.itemcode = 'TEST' enter code here
GROUP BY i.itemcode,
g.warehouse
)src
Looks like following would work:
WITH itemCodesScope AS
(
SELECT 'TEST' as target_ItemCode
),
aggregated_CSSDKMagento_10_Plankvoorraad AS
(
SELECT g.artcode,
g.warehouse,
COUNT(g.aantal) as count_aantal,
SUM(g.aantal) as sum_aantal,
MAX(CASE
WHEN g.transtype = 'N' THEN g.sysmodified
ELSE NULL
END) AS LastDate
FROM dbo.CSSDKMagento_10_Plankvoorraad AS g
JOIN itemCodesScope ON itemCodesScope.target_itemCode = g.artcode
GROUP BY
g.artcode,
g.warehouse
),
aggregated_CSSDKMagento_20_GeenAllocatieWelFiat AS
(
SELECT a.artcode ,
COUNT(a.aantal) as count_aantal,
SUM(a.aantal) as sum_aantal
FROM dbo.CSSDKMagento_20_GeenAllocatieWelFiat AS a
JOIN itemCodesScope ON itemCodesScope.target_itemCode = a.artcode
GROUP BY
a.artcode
),
aggregated_CSSDKMagento_30_AllocatieVoorraad AS
(
SELECT v.artcode ,
COUNT(v.aantal) as count_aantal,
SUM(v.aantal) as sum_aantal
FROM dbo.CSSDKMagento_30_AllocatieVoorraad AS v
JOIN itemCodesScope ON itemCodesScope.target_itemCode = v.artcode
GROUP BY
v.artcode
),
aggregated_CSSDKMagento_50_AllocatieBestellingBinnen AS
(
SELECT b.artcode ,
COUNT(b.aantal) as count_aantal,
SUM(b.aantal) as sum_aantal
FROM dbo.CSSDKMagento_50_AllocatieBestellingBinnen AS b
JOIN itemCodesScope ON itemCodesScope.target_itemCode = b.artcode
GROUP BY
b.artcode
)
SELECT
g.artcode as ItemCode,
g.warehouse,
g.sum_aantal AS Voorraad,
g.LastDate AS LastDate,
g.sum_aantal + ISNULL(a.sum_aantal, 0) + ISNULL(v.sum_aantal, 0) + ISNULL(b.sum_aantal, 0) as sum_aantal,
g.count_aantal + ISNULL(a.count_aantal, 0) + ISNULL(v.count_aantal, 0) + ISNULL(b.count_aantal, 0) as count_aantal
FROM aggregated_CSSDKMagento_10_Plankvoorraad AS g
INNER JOIN dbo.Items AS i
ON (g.artcode = i.ItemCode)
INNER JOIN itemCodesScope
ON itemCodesScope.target_itemCode = i.ItemCode
LEFT JOIN aggregated_CSSDKMagento_20_GeenAllocatieWelFiat AS a
ON (a.artcode = i.ItemCode)
LEFT JOIN aggregated_CSSDKMagento_30_AllocatieVoorraad AS v
ON (v.artcode = i.ItemCode)
LEFT JOIN aggregated_CSSDKMagento_50_AllocatieBestellingBinnen AS b
ON (b.artcode = i.ItemCode)
Explanation
SQL-joins produce Cartesian Products, which most probably led to unexpected results in the initial query. Here there are 4 'amount'-tables which are connected via Joins with conditions 'ON (b.artcode = i.ItemCode)', so if there any table contains several records per condition output will contain several records per ItemCode.
Let's say there are 9 records in a-table with a.artcode per single i.ItemCode, so there is a one-to-many relation. And let's say there is 1 record in b-table per single i.ItemCode. Output of Join will have 9 a.aantal records, but 9 repeated b.aantal records as well. Given that there is an aggregation (group by) it will effect that SUM(b.aantal) in this Joins-query will produce 9-time more than sum(b.aantal) in standalone query on b-table only.
Cartesian Product could be seen more easily, if run the initial query without aggregation:
SELECT *
FROM dbo.CSSDKMagento_10_Plankvoorraad AS g
INNER JOIN dbo.Items AS i
ON (g.artcode = i.ItemCode)
INNER JOIN dbo.CSSDKMagento_20_GeenAllocatieWelFiat AS a
ON (a.artcode = i.ItemCode)
INNER JOIN dbo.CSSDKMagento_30_AllocatieVoorraad AS v
ON (v.artcode = i.ItemCode)
INNER JOIN dbo.CSSDKMagento_50_AllocatieBestellingBinnen AS b
ON (b.artcode = i.ItemCode)
WHERE
i.itemcode = 'TEST'
The fixture was: doing group by aggregation before making joins. Most convenient way for this imho is CTE. With CTE I created 4 temporary tables with aggregates per ItemCode, so temporary tables are one-to-one per ItemCode. Then Joins on one-to-one produce just single output row per ItemCode.

Count for multiple value in table without union all in sql

I have validationErrors with various WIPReason associated with and I want to count based on different WIPReason, I am using Union All and it works but Query is very big with mutiple wip reason more than 10. Please find the query below
SELECT
COUNT(tlv.TransactionLineId) AS TotalErrors,
COUNT(tl.Id) AS TotalLines,
COUNT(tlv.Reason) AS NoWorkRecords,
0 AS ValidationErrors
FROM
dbo.TimesheetCellTransactionLine tctl
INNER JOIN
dbo.TransactionLine tl ON tctl.TransactionLineId = tl.Id
INNER JOIN
dbo.TransactionLineValidation tlv ON tl.Id = tlv.TransactionLineId
INNER JOIN
dbo.WIPReason w ON tlv.Reason = w.Id
WHERE
tl.CurrentStatus = 1
AND w.Id = 4 -- NoWorkRecords
GROUP BY
tlv.TransactionLineId, tl.Id
UNION ALL
SELECT
COUNT(tlv.TransactionLineId) AS TotalErrors,
COUNT(tl.Id) AS TotalLines,
0 AS NoWorkRecords,
COUNT(tlv.Reason) AS ValidationErrors
FROM
dbo.TimesheetCellTransactionLine tctl
INNER JOIN
dbo.TransactionLine tl ON tctl.TransactionLineId = tl.Id
INNER JOIN
dbo.TransactionLineValidation tlv ON tl.Id = tlv.TransactionLineId
INNER JOIN
dbo.WIPReason w ON tlv.Reason = w.Id
WHERE
tl.CurrentStatus = 1
AND w.Id = 1 -- validationErrors
GROUP BY
tlv.TransactionLineId, tl.Id
Is there any other elegant way of doing this for w.Id = 1 to 10
AND w.Id = 1 -- validationErrors
Update :
I want result as columns 10 count columns as I am using this in another big select.
You can use a case statement inside count like this:
SELECT
COUNT(tlv.TransactionLineId) AS TotalErrors,
COUNT(tl.Id) AS TotalLines,
COUNT(case when w.Id = 4 then tlv.Reason else null end) AS NoWorkRecords,
COUNT(case when w.Id = 1 then tlv.Reason else null end) AS ValidationErrors,
... Repeat for remaining w.Id's ...
FROM
dbo.TimesheetCellTransactionLine tctl
INNER JOIN
dbo.TransactionLine tl ON tctl.TransactionLineId = tl.Id
INNER JOIN
dbo.TransactionLineValidation tlv ON tl.Id = tlv.TransactionLineId
INNER JOIN
dbo.WIPReason w ON tlv.Reason = w.Id
WHERE
tl.CurrentStatus = 1
GROUP BY
tlv.TransactionLineId, tl.Id
Note
Since you are using an inner join on tl.Id = tlv.TransactionLineId
TotalErrors/TotalLines are always going to be the same
Grouping by tl.Id and tlv.TransactionLineId is unnecessary
SELECT COUNT(tlv.TransactionLineId) OVER (partition by (w.Id) order by w.Id) AS TotalErrors,
COUNT(tl.Id) OVER (partition by (w.Id) order by w.Id) AS TotalLines,
0 AS NoWorkRecords,
COUNT(tlv.Reason) OVER (partition by (w.Id) order by w.Id) AS ValidationErrors
FROM dbo.TimesheetCellTransactionLine tctl
INNER JOIN dbo.TransactionLine tl ON tctl.TransactionLineId = tl.Id
INNER JOIN dbo.TransactionLineValidation tlv ON tl.Id = tlv.TransactionLineId
INNER JOIN dbo.WIPReason w ON tlv.Reason = w.Id
WHERE tl.CurrentStatus = 1
AND w.Id between 1 and 10 -- validationErrors
GROUP BY tlv.TransactionLineId,
tl.Id,tlv.Reason

Why does adding this field make my query run slow?

The query below runs in less than a second if I take off one field from the select list -- the last one, att. But having it there causes the query to take over a minute. Any thoughts? Note that the subquery inside the left join runs fast on its own.
select p.person_id, cfm.family_id, p.nick_name, p.last_name, s.lookup_value as group_role, gm.active, g.group_id, g.group_name,
g.active as group_active, tg.category, gc.cluster_name, coalesce(a.attendance,0) as att --this field is the culprit
from smgp_group g
join smgp_group_cluster gc on g.group_cluster_id = gc.group_cluster_id
join smgp_member gm on g.group_id = gm.group_id
join core_person p on gm.person_id = p.person_id
join core_family_member cfm on p.person_id = cfm.person_id
join core_lookup s on gm.role_luid = s.lookup_id
join #target_groups tg on g.group_id = tg.group_id
left join (
select at.person_id, goc.group_id, count(at.attended) as attendance from core_occurrence_attendance at
join core_occurrence o on at.occurrence_id = o.occurrence_id
join smgp_group_occurrence goc on o.occurrence_id = goc.occurrence_id
where goc.group_id in (select group_id from #target_groups)
and o.occurrence_start_time between #start_date and #end_date
group by at.person_id, goc.group_id
) a on p.person_id = a.person_id and g.group_id = a.group_id
where tg.category = 'adults' or (tg.category = 'kids' and s.lookup_value in ('Leader-Teacher','Assistant Leader'))
Try running the following -
SELECT p.persON_id, cfm.family_id, p.nick_name,
p.last_name, s.lookup_value as group_role,
gm.active, g.group_id, g.group_name,
g.active as group_active, tg.cATegory,
gc.cluster_name, a.ATtendance
INTO #tempDataset
FROM smgp_group g
JOIN smgp_group_cluster gc
ON g.group_cluster_id = gc.group_cluster_id
JOIN smgp_member gm
ON g.group_id = gm.group_id
JOIN core_persON p
ON gm.persON_id = p.persON_id
JOIN core_family_member cfm
ON p.persON_id = cfm.persON_id
JOIN core_lookup s
ON gm.role_luid = s.lookup_id
JOIN #target_groups tg
ON g.group_id = tg.group_id
LEFT JOIN (SELECT AT.persON_id, goc.group_id, count(AT.ATtended) as ATtendance FROM core_occurrence_ATtendance AT
JOIN core_occurrence o
ON AT.occurrence_id = o.occurrence_id
JOIN smgp_group_occurrence goc
ON o.occurrence_id = goc.occurrence_id
WHERE goc.group_id IN (SELECT group_id
FROM #target_groups)
AND o.occurrence_start_time BETWEEN #start_dATe AND #end_dATe
GROUP BY AT.persON_id, goc.group_id) a
ON p.persON_id = a.persON_id
AND g.group_id = a.group_id
WHERE tg.cATegory = 'adults' or (tg.cATegory = 'kids' AND s.lookup_value IN ('Leader-Teacher','Assistant Leader'))
SELECT persON_id,
family_id,
nick_name,
last_name,
group_role,
active,
group_id,
group_name,
group_active,
cATegory,
cluster_name,
coalesce(ATtendance,0) AS ATT
FROM #tempDataset
If that runs slowly, you can possibly add an index on the temp table, but I would try doing the above as a first step.
The query below runs in 3 seconds and resolved the problem. Thanks.
select at.person_id, goc.group_id, count(at.attended) as attendance
into #a
from core_occurrence_attendance at
join core_occurrence o on at.occurrence_id = o.occurrence_id
join smgp_group_occurrence goc on o.occurrence_id = goc.occurrence_id
where goc.group_id in (select group_id from #target_groups)
and o.occurrence_start_time between #start_date and #end_date
group by at.person_id, goc.group_id
select p.person_id, cfm.family_id, p.nick_name, p.last_name, s.lookup_value as group_role, gm.active, g.group_id, g.group_name,
g.active as group_active, tg.category, gc.cluster_name, coalesce(#a.attendance,0) as att--, --this field is the culprit
from smgp_group g
join smgp_group_cluster gc on g.group_cluster_id = gc.group_cluster_id
join smgp_member gm on g.group_id = gm.group_id
join core_person p on gm.person_id = p.person_id
join core_family_member cfm on p.person_id = cfm.person_id
join core_lookup s on gm.role_luid = s.lookup_id
join #target_groups tg on g.group_id = tg.group_id
left join #a on p.person_id = #a.person_id and g.group_id = #a.group_id
where tg.category = 'adults' or (tg.category = 'kids' and s.lookup_value in ('Leader-Teacher','Assistant Leader'))

How to link sql sub queries together?

is it possible to link the following sub query (see below.) The first three sub queries work fine however I'm struggling to see how to do the rest any guidance would be great cheers.
Ps. apologies for the long code
SELECT c.[Status],
c.CompanyId,
c.Name,
(SELECT count(DISTINCT usr.UserID)
FROM [ondemand.10cms.com].Security.[user] usr
INNER JOIN [ondemand.10cms.com].Company.Company
ON usr.CompanyID = Company.CompanyID
WHERE usr.CompanyID = c.CompanyID) AS TotalUsers,
(SELECT sum (CASE WHEN usr.Status = 2 THEN 1 ELSE 0 END)
FROM [ondemand.10cms.com].Security.[user] usr
INNER JOIN [ondemand.10cms.com].Company.Company
ON usr.CompanyID = Company.CompanyID
WHERE usr.CompanyID = c.CompanyID) AS ActiveUsers,
(SELECT sum (CASE WHEN usr.Status = 3 THEN 1 ELSE 0 END)
FROM [ondemand.10cms.com].Security.[User] usr
INNER JOIN [ondemand.10cms.com].Company.Company
ON usr.CompanyID = Company.CompanyID WHERE usr.CompanyID = c.CompanyID) AS SuspendedUsers,
(Select COUNT (distinct usrs.id)
From [ondemand.10cms.com].Security.UserSession usrs
inner join [ondemand.10cms.com].Security.[user] usr on usrs.UserID=usr.UserID
) as TotalLogin,
(Select
COUNT( MerchandisingModule.Name)
From [ondemand.10cms.com].Project.Template
inner join [ondemand.10cms.com].Project.MerchandisingModule on Template.TemplateID= MerchandisingModule.TemplateId
)as CurrentModules,
(Select
count(MerchandisingModule.CreatedDate)
from [ondemand.10cms.com].Project.MerchandisingModule
inner join [ondemand.10cms.com].Project.Template on Template.TemplateID= MerchandisingModule.TemplateId
)as ModulesCreated,
(Select
count(mm.UpdatedDate)
from [ondemand.10cms.com].Project.MerchandisingModule mm
inner join [ondemand.10cms.com].Project.Template on Template.TemplateID= mm.TemplateId
)as ModulesUpdated,
(Select
COUNT(MA.MerchandisingAreaID)
from [ondemand.10cms.com].Project.MerchandisingArea MA
inner join [ondemand.10cms.com].Project.Project on Project.ProjectID= MA.ProjectID
) as Currentareas,
(Select
COUNT (MA.name)
from [ondemand.10cms.com].Project.MerchandisingArea MA
inner join [ondemand.10cms.com].Project.Project on Project.ProjectID= MA.ProjectID
) as AreasCreated,
(select
COUNT (MerchandisingArea.UpdatedDate)
from [ondemand.10cms.com].Project.MerchandisingArea
inner join [ondemand.10cms.com].Project.Project on Project.ProjectID= MerchandisingArea.ProjectID
) as AreasUpdated,
(Select
SUM ( case when MA.PublishStatus = 1 then 1 else 0 end)
from [ondemand.10cms.com].Project.MerchandisingArea MA
inner join [ondemand.10cms.com].Project.PublishingStatus on PublishingStatus.PublishStatusId = MA.PublishStatus
) as SuccessPublished,
(Select
SUM ( case when MA.PublishStatus = 3 then 1 else 0 end)
from [ondemand.10cms.com].Project.MerchandisingArea MA
inner join [ondemand.10cms.com].Project.PublishingStatus on PublishingStatus.PublishStatusId= MA.PublishStatus
) as FailedPublished
from [ondemand.10cms.com].Company.Company c
This was fixed by adding another inner join to each sub query and also another where clause