Easiest way to get a total count and a count of a

2019-01-28 03:53发布

问题:

I was trying to do this:

SELECT COUNT(*),
        (
            SELECT COUNT(*) FROM attend
            WHERE (DATEPART(WEEKDAY,start_date) = 2 OR DATEPART(WEEKDAY,start_date) = 6)
            AND empl_no = 12345
        )
        FROM attend as a
 WHERE empl_no = 12345

But this seems a little ugly. Is there a better way to do this?

回答1:

You could use a CTE:

WITH T1 AS (
    SELECT DATEPART(WEEKDAY,start_date) AS weekday
    FROM attend
    WHERE empl_no = 12345
)
SELECT
    (SELECT COUNT(*) FROM T1) AS total,
    (SELECT COUNT(*) FROM T1 WHERE weekday = 2 OR weekday = 6) AS subset


回答2:

Use:

SELECT COUNT(*) AS total,
       SUM(CASE 
             WHEN DATEPART(WEEKDAY, t.start_date) IN (2,6) THEN 1 
             ELSE 0 
           END) AS weekday
  FROM ATTEND t
 WHERE t.empl_no = 12345


回答3:

CUBE and ROLLUP are very useful for dealing with final and intermediate aggregates all in one shot. For this type of question CUBE would be a good fit if the final and intermediate totals were needed so this and similar questions could be answered without additional queries from the source table. I've found CUBE very useful for avoiding round trips to the DB. However, in the case where the exact requirements are known ahead of time a single focused select (nicely demonstrated by @nate c) makes the most sense.

DECLARE @T1 TABLE (total int, weekday int)

INSERT INTO @T1
SELECT COUNT(1), DATEPART(WEEKDAY,start_date)
FROM attend
WHERE empl_no = 12345
GROUP BY DATEPART(WEEKDAY,start_date) WITH CUBE

SELECT 
    (SELECT Total FROM @T1 WHERE weekday is NULL) AS total,
    (SELECT SUM(weekday) FROM @T1 WHERE weekday = 2 or weekday = 6) AS subset

-- continue using @T1 or a table variable was seriously overkill