Using Access 2007, I am trying to run a query that outputs and organizes a long string of union queries into a list of data for a report. The report is something my supervisor passes to me and I want SQL just to do the leg work so I can export to an Excel file then copy paste. The issue:
The data I am using is imported from a separate Miscrosoft Excel from another department, and the clerk does not follow basic database rules and there is no hope of changing the system. The "LOSING_UNIT" column contains more than one example at times (i.e. some LOSING_UNITS are "A Trp" others are "A Trp B Trp C Trp" with no comma, semi-colon or any other form besides whitespace to determine the next Unit)
I need the queries to perform similar to a Like relation for the groupby if this is possible, so that any record containing "A Trp" becomes one total for Completed, one total for Remaining, etc. (currently my output comes as
Title LOSING_UNIT Total
Completed Directives A TRP 3-71 CAV 12
Delinquent Directives A TRP 3-71 CAV 2
Missing GUIC A TRP 3-71 CAV 2
Remaining Directives A TRP 3-71 CAV 8
Missing GUIC A TRP 3-71 CAV B TRP 3-71 CAV C Co 3-71 CAV 1
Remaining Directives A TRP 3-71 CAV B TRP 3-71 CAV C Co 3-71 CAV 1
If this is not possible option 2: be able to orderby the length of the string so that all the solo LOSING_UNITS come out on top, with an alphabetical ORDERBY second. I have not been able to find a way to do this without generating a "Aggregate Function" error.
Select 'Completed Directives' AS Title, LOSING_UNIT, Count(PSD_ID) AS Total
FROM [Lateral_Transfers_Closed_Canceled_LINKED]
WHERE (LOSING_PARENT_UIC = "WJJ4AA")
AND (STATUS = "Complete")
GROUP BY LOSING_UNIT
ORDER BY LOSING_UNIT
UNION
SELECT 'Remaining Directives', LOSING_UNIT, COUNT(PSD_ID)
FROM [Lateral_Transfers_LINKED] AS LT
WHERE (LOSING_PARENT_UIC = "WJJ4AA")
GROUP BY LOSING_UNIT
ORDER BY LOSING_UNIT
UNION
SELECT 'Delinquent Directives' AS Title,LOSING_UNIT, Count(PSD_ID) AS TOTAL
FROM [Lateral_Transfers_LINKED] AS LT
WHERE LT.SUSPENSE_DATE BETWEEN #1/01/2014# AND DATE()
AND (LOSING_PARENT_UIC = "WJJ4AA")
GROUP BY LOSING_UNIT
ORDER BY LOSING_UNIT
UNION
SELECT 'Missing GUIC', LOSING_UNIT, Count(PSD_ID)
FROM [Lateral_Transfers_LINKED] AS LT
WHERE (LOSING_PARENT_UIC = "WJJ4AA")
AND ( GUIC Is Null OR GUIC = "Not Activated" )
AND LUIC Is NOT Null
GROUP BY LOSING_UNIT
ORDER BY LOSING_UNIT
UNION
SELECT 'Missing LUIC', LOSING_UNIT, COUNT(PSD_ID)
FROM [Lateral_Transfers_LINKED] AS LT
WHERE (LOSING_PARENT_UIC = "WJJ4AA")
AND LUIC Is Null
AND GUIC Is NOT Null
GROUP BY LOSING_UNIT
ORDER BY LOSING_UNIT
UNION
SELECT 'On Hold', LOSING_UNIT, Count(PSD_ID)
FROM [Lateral_Transfers_LINKED] AS LT
WHERE (LOSING_PARENT_UIC = "WJJ4AA")
AND (LT.SERIAL_NUMBER LIKE "Temp. Hold")
GROUP BY LOSING_UNIT
ORDER BY LOSING_UNIT;
EDIT:
To be a bit more clear, here is how I have tried to adjust the SQL based off of other articles SQL Query - Using Order By in UNION
Select '' AS Title, LOSING_UNIT, '' AS Total
FROM(
Select 'Completed Directives', LOSING_UNIT, Count(PSD_ID)
FROM [Lateral_Transfers_Closed_Canceled_LINKED]
WHERE (LOSING_PARENT_UIC = "WJJ4AA")
AND (STATUS = "Complete")
UNION
SELECT 'Remaining Directives', LOSING_UNIT, COUNT(PSD_ID)
FROM [Lateral_Transfers_LINKED] AS LT
WHERE (LOSING_PARENT_UIC = "WJJ4AA")
UNION
SELECT 'Delinquent Directives' AS Title,LOSING_UNIT, Count(PSD_ID) AS TOTAL
FROM [Lateral_Transfers_LINKED] AS LT
WHERE LT.SUSPENSE_DATE BETWEEN #1/01/2014# AND DATE()
AND (LOSING_PARENT_UIC = "WJJ4AA")
UNION
SELECT 'Missing GUIC', LOSING_UNIT, Count(PSD_ID)
FROM [Lateral_Transfers_LINKED] AS LT
WHERE (LOSING_PARENT_UIC = "WJJ4AA")
AND ( GUIC Is Null OR GUIC = "Not Activated" )
AND LUIC Is NOT Null
UNION
SELECT 'Missing LUIC', LOSING_UNIT, COUNT(PSD_ID)
FROM [Lateral_Transfers_LINKED] AS LT
WHERE (LOSING_PARENT_UIC = "WJJ4AA")
AND LUIC Is Null
AND GUIC Is NOT Null
UNION
SELECT 'On Hold', LOSING_UNIT, Count(PSD_ID)
FROM [Lateral_Transfers_LINKED] AS LT
WHERE (LOSING_PARENT_UIC = "WJJ4AA")
AND (LT.SERIAL_NUMBER LIKE "Temp. Hold")
GROUP BY LOSING_UNIT
ORDER BY LOSING_UNIT)
GROUP BY LOSING_UNIT
ORDER BY MID(LOSING_UNIT, 1, 5), LOSING_UNIT;
I did also attempt to put the aggregate into the first SELECT with no change in results.
EDIT:
- A TRP 3-71 CAV
- A TRP 3-71 CAV B TRP 3-71 CAV C Co 3-71 CAV
- A TRP 3-71 CAV C TRP 3-71 CAV HHT 3-71 CAV
- A TRP 3-71 CAV B TRP 3-71 CAV
- A TRP 3-71 CAV C TRP 3-71 CAV
- B TRP 3-71 CAV
- B TRP 3-71 CAV A TRP 3-71 CAV
- B TRP 3-71 CAV C TRP 3-71 CAV
- C TRP 3-71 CAV B TRP 3-71 CAV HHT 3-71 CAV
- C TRP 3-71 CAV *HHT 3-71 CAV
- HHT 3-71 CAV A TRP 3-71 CAV C TRP 3-71 CAV
- HHT 3-71 CAV A TRP 3-71 CAV
- HHT 3-71 CAV A TRP 3-71 CAV B TRP 3-71 CAV C TRP 3-71 CAV
- HHT 3-71 CAV C TRP 3-71 CAV
The Final Solution
Select 'Completed Directives' AS Title, ValuesToFind.LOSING_UNIT, Count(PSD_ID) AS Total
FROM
[Lateral_Transfers_LINKED] AS LT
left join [ValuesToFind]
on LT.LOSING_UNIT LIKE '*' + ValuesToFind.LOSING_UNIT + '*'
WHERE (LOSING_PARENT_UIC = "WJJ4AA")
AND (STATUS = "Complete")
GROUP BY ValuesToFind.LOSING_UNIT
ORDER BY ValuesToFind.LOSING_UNIT
UNION
SELECT 'Remaining Directives', ValuesToFind.LOSING_UNIT, COUNT(PSD_ID)
FROM
[Lateral_Transfers_LINKED] AS LT
left join [ValuesToFind]
on LT.LOSING_UNIT LIKE '*' + ValuesToFind.LOSING_UNIT + '*'
WHERE (LOSING_PARENT_UIC = "WJJ4AA")
GROUP BY ValuesToFind.LOSING_UNIT
ORDER BY ValuesToFind.LOSING_UNIT
UNION
SELECT 'Delinquent Directives' AS Title, ValuesToFind.LOSING_UNIT, Count(PSD_ID) AS TOTAL
FROM
[Lateral_Transfers_LINKED] AS LT
left join [ValuesToFind]
on LT.LOSING_UNIT LIKE '*' + ValuesToFind.LOSING_UNIT + '*'
WHERE LT.SUSPENSE_DATE BETWEEN #1/01/2014# AND DATE()
AND (LOSING_PARENT_UIC = "WJJ4AA")
GROUP BY ValuesToFind.LOSING_UNIT
ORDER BY ValuesToFind.LOSING_UNIT
UNION
SELECT 'Missing GUIC', ValuesToFind.LOSING_UNIT, Count(PSD_ID)
FROM
[Lateral_Transfers_LINKED] AS LT
left join [ValuesToFind]
on LT.LOSING_UNIT LIKE '*' + ValuesToFind.LOSING_UNIT + '*'
WHERE (LOSING_PARENT_UIC = "WJJ4AA")
AND ( GUIC Is Null OR GUIC = "Not Activated" )
AND LUIC Is NOT Null
GROUP BY ValuesToFind.LOSING_UNIT
ORDER BY ValuesToFind.LOSING_UNIT
UNION
SELECT 'On Hold', ValuesToFind.LOSING_UNIT, Count(PSD_ID)
FROM
[Lateral_Transfers_LINKED] AS LT
LEFT JOIN [ValuesToFind]
on LT.LOSING_UNIT LIKE '*' + ValuesToFind.LOSING_UNIT + '*'
WHERE (LOSING_PARENT_UIC = "WJJ4AA")
AND (LT.SERIAL_NUMBER LIKE "Temp. Hold")
GROUP BY ValuesToFind.LOSING_UNIT
ORDER BY ValuesToFind.LOSING_UNIT
Many thanks to Kyle