views:

55

answers:

2

I have the following table: alt text

I am trying to create an SQL query that returns a table that returns three fields: Year (ActionDate), Count of Built (actiontype = 12), Count of Lost (actiontype = a few different ones) Bascially, ActionType is a lookup code. So, I'd get back something like:

       YEAR   CountofBuilt  CountofLost
        1905        30          18
        1929        12          99
        1940        60           1 
etc....

I figured this would take two SELECT statements put together with a UNION. I tried the following below but it only spits back two columns (year and countbuilt). My countLost field doesn't appear

My sql currently (MS Access):

SELECT tblHist.ActionDate, Count(tblHist.ActionDate) as countBuilt
FROM ...
WHERE ((tblHist.ActionType)=12)
GROUP BY tblHist.ActionDate
UNION
SELECT tblHist.ActionDate, Count(tblHist.ActionDate) as countLost
FROM ...
WHERE (((tblHist.ActionType)<>2) AND
((tblHist.ActionType)<>3))
GROUP BY tblHist.ActionDate;
+1  A: 

You should not use UNION for such queries. There are many ways to do what you want, for example Updated to fit access syntax

SELECT tblHist.ActionDate,
COUNT(SWITCH(tblHist.ActionType = 12,1)) as countBuilt,
COUNT(SWITCH(tblHist.ActionType <>1 OR tblHist.ActionType <>2 OR ...,1)) as countLost
FROM ..
WHERE ....
GROUP BY tblHist.ActionDate
a1ex07
For the conditionals for creating countLost, it's almost easier for me to state what ActionType #s shouldn't but used. For example, if I want all ActionTypes that are not 2, 3 or 9, can I just plug that into <Another numbers> above or is it expecting the opposite? Can I enter a range of numbers?
stuttsdc
You can enter any condition you want (`IN`,`NOT IN`, subquery result, etc).
a1ex07
The idea is that `COUNT` returns a count of non-null values, and `CASE` has default `ELSE NULL`;
a1ex07
Does MS Access support CASE?
Leigh
You can also use OMG Ponies solution with `IIF`, I prefer `CASE` because it has the same syntax among almost all servers, while each DB vendor has it's own idea about `IF`/`IIF`.
a1ex07
Oops. It has case,but it's also a bit different syntax. I need to update my answer.
a1ex07
Yeah, that's why I had to change mine - there is CASE in Access, but it isn't ANSI :/
OMG Ponies
Thank you to everyone w/your quick input. I will refer back to both of your solutions in time.
stuttsdc
Too bad Access does not support standard CASE. It is much prettier ;)
Leigh
Changed to use `switch`. It seems that this function has been supported for quite a while.
a1ex07
Learn something new every day..
Leigh
There is not CASE in Jet/ACE/Access SQL.
David-W-Fenton
+3  A: 

Use:

  SELECT h.actiondate,
         SUM(IIF(h.actiontype = 12, 1, 0)) AS numBuilt,
         SUM(IIF(h.actiontype NOT IN (2,3), 1, 0)) AS numLost
    FROM tblHist h
GROUP BY h.actiondate
OMG Ponies
I get an error: "Syntax error (missing operator) in query expression 'SUM(CASE WHEN tblHist.ActionType=12 THEN 1 ELSE 0 END)'
stuttsdc
@stuttsdc: Refresh the page - I noticed you were using Access after posting the answer, and updated.
OMG Ponies
see you updated it. Well, I still get an error: Syntax error (missing operator) in query expression 'SUM(IIF(tblHist.ActionType=12 THEN 1 ELSE 0 END))'
stuttsdc
@stuttsdc: That doesn't resemble my answer, which hasn't changed for over 5 minutes now.
OMG Ponies
I should probably note this code is being called by Coldfusion <cfquery> tags, if that makes any difference. Ultimately, yes, it's an access db.
stuttsdc
My bad. Just copy/pasted your code and it did run. I suspect a1ex07's code works too but I have yet to try it.
stuttsdc