简体   繁体   中英

SQL How to count case

I am trying to case out a select statement. However, there are multiple results for 7am 8am 9am etc. I'd like the results to show:

Count Time
10 7am
6 8am

etc. Instead, it is showing all the 7ams all the 8ams etc.

select
case
when aq.datestarted between to_date( '22-MAY-2014 07:00:00', 'dd-mon-yyyy hh24:mi:ss' ) and to_date( '22-MAY-2014 " 07:59:59', 'dd-mon-yyyy hh24:mi:ss' ) then '7am'
when aq.datestarted between to_date( '22-MAY-2014 08:00:00', 'dd-mon-yyyy hh24:mi:ss' ) and to_date( '22-MAY-2014 " 08:59:59', 'dd-mon-yyyy hh24:mi:ss' ) then '8am'
when aq.datestarted between to_date( '22-MAY-2014 09:00:00', 'dd-mon-yyyy hh24:mi:ss' ) and to_date( '22-MAY-2014 " 09:59:59', 'dd-mon-yyyy hh24:mi:ss' ) then '9am'
when aq.datestarted between to_date( '22-MAY-2014 10:00:00', 'dd-mon-yyyy hh24:mi:ss' ) and to_date( '22-MAY-2014 " 10:59:59', 'dd-mon-yyyy hh24:mi:ss' ) then '10am'
when aq.datestarted between to_date( '22-MAY-2014 11:00:00', 'dd-mon-yyyy hh24:mi:ss' ) and to_date( '22-MAY-2014 " 11:59:59', 'dd-mon-yyyy hh24:mi:ss' ) then '11am'
END as Time
from archivedqueue aq
where aq.datestarted between to_date( '22-MAY-2014 07:00:00', 'dd-mon-yyyy hh24:mi:ss' ) and to_date( '22-MAY-2014 " 11:59:59', 'dd-mon-yyyy hh24:mi:ss' )
select COUNT(*), Time
FROM
(SELECT
    case
    when aq.datestarted between to_date( '22-MAY-2014 07:00:00', 'dd-mon-yyyy hh24:mi:ss' ) and to_date( '22-MAY-2014 " 07:59:59', 'dd-mon-yyyy hh24:mi:ss' ) then '7am'
    when aq.datestarted between to_date( '22-MAY-2014 08:00:00', 'dd-mon-yyyy hh24:mi:ss' ) and to_date( '22-MAY-2014 " 08:59:59', 'dd-mon-yyyy hh24:mi:ss' ) then '8am'
    when aq.datestarted between to_date( '22-MAY-2014 09:00:00', 'dd-mon-yyyy hh24:mi:ss' ) and to_date( '22-MAY-2014 " 09:59:59', 'dd-mon-yyyy hh24:mi:ss' ) then '9am'
    when aq.datestarted between to_date( '22-MAY-2014 10:00:00', 'dd-mon-yyyy hh24:mi:ss' ) and to_date( '22-MAY-2014 " 10:59:59', 'dd-mon-yyyy hh24:mi:ss' ) then '10am'
    when aq.datestarted between to_date( '22-MAY-2014 11:00:00', 'dd-mon-yyyy hh24:mi:ss' ) and to_date( '22-MAY-2014 " 11:59:59', 'dd-mon-yyyy hh24:mi:ss' ) then '11am'
    END as Time
    from archivedqueue aq
    where aq.datestarted between to_date( '22-MAY-2014 07:00:00', 'dd-mon-yyyy hh24:mi:ss' ) and to_date( '22-MAY-2014 " 11:59:59', 'dd-mon-yyyy hh24:mi:ss' )) tempTable
GROUP BY Time

Group by Time will combine all the 7ams,8ams, together. Count(*) counts the number of rows in each group.

SELECT COUNT(*) AS Count, Time
  FROM (SELECT case
               when aq.datestarted between to_date( '22-MAY-2014 07:00:00', 'dd-mon-yyyy hh24:mi:ss' ) and to_date( '22-MAY-2014 07:59:59', 'dd-mon-yyyy hh24:mi:ss' ) then '7am'
               when aq.datestarted between to_date( '22-MAY-2014 08:00:00', 'dd-mon-yyyy hh24:mi:ss' ) and to_date( '22-MAY-2014 08:59:59', 'dd-mon-yyyy hh24:mi:ss' ) then '8am'
               when aq.datestarted between to_date( '22-MAY-2014 09:00:00', 'dd-mon-yyyy hh24:mi:ss' ) and to_date( '22-MAY-2014 09:59:59', 'dd-mon-yyyy hh24:mi:ss' ) then '9am'
               when aq.datestarted between to_date( '22-MAY-2014 10:00:00', 'dd-mon-yyyy hh24:mi:ss' ) and to_date( '22-MAY-2014 10:59:59', 'dd-mon-yyyy hh24:mi:ss' ) then '10am'
               when aq.datestarted between to_date( '22-MAY-2014 11:00:00', 'dd-mon-yyyy hh24:mi:ss' ) and to_date( '22-MAY-2014 11:59:59', 'dd-mon-yyyy hh24:mi:ss' ) then '11am'
               END as Time
          FROM archivedqueue aq
         WHERE aq.datestarted between to_date( '22-MAY-2014 07:00:00', 'dd-mon-yyyy hh24:mi:ss' ) and to_date( '22-MAY-2014 11:59:59', 'dd-mon-yyyy hh24:mi:ss' )
       ) name_required
 GROUP BY Time
 ORDER BY Time;

The sub-query is what you wrote (apart from a fixup in the second TO_DATE in the various BETWEEN conditions — it is easier to spot problems when you can see the code without horizontal scrolling!), marginally reformatted. Note that the ORDER BY is imperfect because the sort is text-based (so the 10am and 11am entries will appear before the 7am to 9am entries). If you don't like that, use a text-sortable format such as 07 or 0700 or 0700-07:59 instead of the 'am'-tagged times.

This is not extensible. You need to work harder on what's in the CASE statement.

Maybe:

TO_CHAR(aq.datestarted, 'yyyy-mm-dd hh24:00') AS time

The restriction condition in the WHERE clause then provides the correct limits on the search.

SELECT COUNT(*) AS Count, TO_CHAR(aq.datestarted, 'yyyy-mm-dd hh:00') AS time
  FROM archivedqueue aq
 WHERE aq.datestarted BETWEEN to_date('22-MAY-2014 07:00:00', 'dd-mon-yyyy hh24:mi:ss')
                          AND to_date('22-MAY-2014 11:59:59', 'dd-mon-yyyy hh24:mi:ss')
 GROUP BY Time
 ORDER BY Time;

To get it working how you'd expect, use what's below... However, there's probably a better way than hardcoding dates and times.

SELECT COUNT(*) AS 'Count', 
        CASE 
            WHEN aq.datestarted BETWEEN to_date( '22-MAY-2014 07:00:00', 'dd-mon-yyyy hh24:mi:ss' ) AND to_date( '22-MAY-2014 " 07:59:59', 'dd-mon-yyyy hh24:mi:ss' ) THEN '7am'
            WHEN aq.datestarted BETWEEN to_date( '22-MAY-2014 08:00:00', 'dd-mon-yyyy hh24:mi:ss' ) AND to_date( '22-MAY-2014 " 08:59:59', 'dd-mon-yyyy hh24:mi:ss' ) THEN '8am'
            WHEN aq.datestarted BETWEEN to_date( '22-MAY-2014 09:00:00', 'dd-mon-yyyy hh24:mi:ss' ) AND to_date( '22-MAY-2014 " 09:59:59', 'dd-mon-yyyy hh24:mi:ss' ) THEN '9am'
            WHEN aq.datestarted BETWEEN to_date( '22-MAY-2014 10:00:00', 'dd-mon-yyyy hh24:mi:ss' ) AND to_date( '22-MAY-2014 " 10:59:59', 'dd-mon-yyyy hh24:mi:ss' ) THEN '10am'
            WHEN aq.datestarted BETWEEN to_date( '22-MAY-2014 11:00:00', 'dd-mon-yyyy hh24:mi:ss' ) AND to_date( '22-MAY-2014 " 11:59:59', 'dd-mon-yyyy hh24:mi:ss' ) THEN '11am'
        END AS 'Time'
FROM archivedqueue aq
WHERE aq.datestarted BETWEEN to_date( '22-MAY-2014 07:00:00', 'dd-mon-yyyy hh24:mi:ss' 
GROUP BY CASE 
            WHEN aq.datestarted BETWEEN to_date( '22-MAY-2014 07:00:00', 'dd-mon-yyyy hh24:mi:ss' ) AND to_date( '22-MAY-2014 " 07:59:59', 'dd-mon-yyyy hh24:mi:ss' ) THEN '7am'
            WHEN aq.datestarted BETWEEN to_date( '22-MAY-2014 08:00:00', 'dd-mon-yyyy hh24:mi:ss' ) AND to_date( '22-MAY-2014 " 08:59:59', 'dd-mon-yyyy hh24:mi:ss' ) THEN '8am'
            WHEN aq.datestarted BETWEEN to_date( '22-MAY-2014 09:00:00', 'dd-mon-yyyy hh24:mi:ss' ) AND to_date( '22-MAY-2014 " 09:59:59', 'dd-mon-yyyy hh24:mi:ss' ) THEN '9am'
            WHEN aq.datestarted BETWEEN to_date( '22-MAY-2014 10:00:00', 'dd-mon-yyyy hh24:mi:ss' ) AND to_date( '22-MAY-2014 " 10:59:59', 'dd-mon-yyyy hh24:mi:ss' ) THEN '10am'
            WHEN aq.datestarted BETWEEN to_date( '22-MAY-2014 11:00:00', 'dd-mon-yyyy hh24:mi:ss' ) AND to_date( '22-MAY-2014 " 11:59:59', 'dd-mon-yyyy hh24:mi:ss' ) THEN '11am'
        END

You just want this:

select count(*) count, hour(datestarted) time
from rchivedqueue
where datestarted between to_date( '22-MAY-2014 07:00:00', 'dd-mon-yyyy hh24:mi:ss' ) and to_date( '22-MAY-2014 " 11:59:59', 'dd-mon-yyyy hh24:mi:ss' )
group by hour(datestarted)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM