I have the SQL statement, working in SQL Server 2016, below where I'm getting records from an INNER SELECT UNION ALL statement and in the OUTER SELECT I'm trying to extract those records that meet the HAVING COUNT code however, my code is bringing back no records.
Here are the records from my INNER SELECT statement with UNION ALL:
LocationSysID | LocationName | AgentNo | RepID | RepName | Count | RN |
---|---|---|---|---|---|---|
5 | A-MAX | 22810 | 17025 | mel | 339 | 1 |
43 | ADV | 21371 | 17025 | mel | 100 | 1 |
43 | ADV | 21371 | 17025 | mel | 0 | 2 |
94 | ALPINE | 21249 | 17025 | mel | 64 | 1 |
94 | ALPINE | 21249 | 17025 | mel | 0 | 2 |
126 | AMS | 21537 | 17025 | mel | 333 | 1 |
138 | ADV | 22812 | 17025 | mel | 1180 | 1 |
I am trying via the OUTER SELECT to get those records from the INNER select statement where the COUNT(LocationSysID) > 1. So that the 4 records where the LocationSysID is 43 and 94 would be returned.
Any help/direction would be appreciated. Thanks.
Here is my SQL code:
SELECT x.LocationSysID, x.LocationName, x.AgentNo, x.RepID, x.RepName, x.TotalCount, x.RN
FROM (
SELECT q.LocationSysID, q.LocationName, q.AgentNo, q.RepID, q.RepName, q.QuoteCount as TotalCount, '1' as RN
FROM #tempYesQuotes q
WHERE q.QuoteCount > 0
--ORDER BY LocationSysID asc;
UNION ALL
SELECT p.LocationSysID, p.LocationName, p.AgentNo, p.RepID, p.RepName, p.PolicyCount as TotalCount, '2' as RN
FROM #tempNoNewPolicies p
WHERE p.PolicyCount = 0
--ORDER BY LocationSysID asc, RN asc;
) x
GROUP BY LocationSysID, LocationName, AgentNo, RepID, RepName, TotalCount, RN
HAVING COUNT(LocationSysID) > 1
ORDER BY LocationSysID asc, RN asc;
The reason you are seeing the results that you describe in the question is because you group by all these fields:
GROUP BY LocationSysID, LocationName, AgentNo, RepID, RepName, TotalCount, RN
The values in TotalCount
and RN
are not the same, so each group has one row. Hence COUNT()
function never returns anything but 1
.
So, if you simply change your GROUP BY
clause and remove columns TotalCount, RN
from it you'll get the results that you expect.
But, with the query structure that you have you'll have to remove these columns from the final result set as well.
I'm guessing that you want to keep them. To achieve that I'd recommend to use windowed COUNT() OVER()
function instead of a plain COUNT
.
I am using CTEs here to make the query readable. You can inline them into one large query if you want. It doesn't affect the performance.
WITH
CTE_Union
AS
(
SELECT q.LocationSysID, q.LocationName, q.AgentNo, q.RepID, q.RepName, q.QuoteCount as TotalCount, '1' as RN
FROM #tempYesQuotes q
WHERE q.QuoteCount > 0
--ORDER BY LocationSysID asc;
UNION ALL
SELECT p.LocationSysID, p.LocationName, p.AgentNo, p.RepID, p.RepName, p.PolicyCount as TotalCount, '2' as RN
FROM #tempNoNewPolicies p
WHERE p.PolicyCount = 0
--ORDER BY LocationSysID asc, RN asc;
)
,CTE_RowCount
AS
(
SELECT
LocationSysID, LocationName, AgentNo, RepID, RepName, TotalCount, RN
,COUNT(*) OVER (PARTITION BY LocationSysID) AS LocationCount
FROM
CTE_Union
)
SELECT
LocationSysID, LocationName, AgentNo, RepID, RepName, TotalCount, RN
FROM
CTE_RowCount
WHERE
LocationCount > 1
ORDER BY
LocationSysID asc, RN asc
;