If all values of StateAbbr that we want to return appear in rows in DataWarehouse table, we can use conditional aggregation.
As a demonstration:
SELECT dw.StateAbbr
, SUM(CASE WHEN dw.FiscalYear = 2017 AND dw.MaltreatmentSetCode != '999' AND dw.MaltreatmentSetCode != '' THEN 1 ELSE 0 END) AS cnt
FROM DataWarehouse dw
GROUP BY dw.StateAbbr
ORDER BY dw.StateAbbr ASC
Note that for each row, the CASE expression is going to be evaluated, returning either 0 or 1, and the SUM() aggregate will add the 1s and 0s up to get us a count.
If there's values of StateAbbr that should be returned by that are not in the DateWarehouse table, then we need a rowsource for those values. (Frequently, these values are in "dimension" tables in a data mart.)
Assuming Abbr is unique in the dwstate table... if this query returns the distinct list of state abbr we need to return:
SELECT s.Abbr
FROM dwstate s
ORDER BY s.Abbr
Then we could do something like this:
SELECT s.Abbr AS StateAbbr
, SUM(CASE WHEN dw.FiscalYear = 2017 AND dw.MaltreatmentSetCode != '999' AND dw.MaltreatmentSetCode != '' THEN 1 ELSE 0 END) AS cnt
FROM dwstate s
LEFT
JOIN DataWarehouse dw
ON dw.StateAbbr = s.Abbr
GROUP BY s.Abbr
ORDER BY s.Abbr ASC
These examples omit the bit about the subquery; it's not clear (to me) which part of the specification that part is meant to satisfy.
SELECT DISTINCT StateAbbr
FROM DataWarehouse
WHERE (NOT MaltreatmentSetCode = '999' )
AND FiscalYear = 2017
If that subquery is meant to return the set of StateAbbr that we are supposed to return, then we can use that as a rowsource in place of dwstate ...
SELECT s.Abbr AS StateAbbr
, SUM(CASE WHEN dw.FiscalYear = 2017 AND dw.MaltreatmentSetCode != '999' AND dw.MaltreatmentSetCode != '' THEN 1 ELSE 0 END) AS cnt
FROM ( -- unique list of state abbreviations
SELECT n.StateAbbr AS Abbr
FROM DataWarehouse n
WHERE (NOT n.MaltreatmentSetCode = '999' )
AND n.FiscalYear = 2017
GROUP BY n.StateAbbr
) s
LEFT
JOIN DataWarehouse dw
ON dw.StateAbbr = s.Abbr
GROUP BY s.Abbr
ORDER BY s.Abbr ASC
DISTINCT StateAbbrdoes not make sense in you query since you are already usingGROUP BY StateAbbr