根据一组日期获取计数

时间:2015-05-15 20:34:19

标签: sql oracle11g

我有两张桌子:

表1中的字段

o_id (Fk),
dt

我有表2

o_id (Fk),
attr1 (Number)

我的目标是计算attr1出现的次数,其中值为0-10,11-20,21 +。然后,我需要将这些事件与表1中的dt分组。

为了更清楚,我提供了一个示例输出:

|   Date   |count(0-10) | count(11-20) | count(21+) |
-----------------------------------------------------
|  01/13   |       3    |         5    |     13     |
|  02/13   |       2    |         7    |     10     |

这是我能得到的最接近的但是效果不好:

SELECT
    t1.dt,
   (select count(tt2.o_id) from table1 tt1, table2 tt2 WHERE attr1 BETWEEN 0 AND 10),
   (select count(tt2.o_id) from table1 tt1, table2 tt2 WHERE attr1 BETWEEN 11 AND 20),
   (select count(tt2.o_id) from table1 tt1, table2 tt2 WHERE attr1 > 21),
FROM
   table1 t1, table2 t2
WHERE
   t1.o_id = t2.o_id
GROUP BY
   t1.dt;

我现在得到的结果:

|   Date   |count(0-10) | count(11-20) | count(21+) |
-----------------------------------------------------
|  01/13   |       3    |         5    |     13     |
|  02/13   |       3    |         5    |     13     |
|  02/14   |       3    |         5    |     13     |
|  02/15   |       3    |         5    |     13     |
|  02/16   |       3    |         5    |     13     |
|  02/17   |       3    |         5    |     13     |
|  02/18   |       3    |         5    |     13     |

只是在计数列内重复。

4 个答案:

答案 0 :(得分:2)

您不需要子查询。这将做你想要的:

SELECT
    t1.dt,
    count(CASE WHEN attr1 BETWEEN  0 AND 10 THEN 1 END),
    count(CASE WHEN attr1 BETWEEN 11 AND 20 THEN 1 END),
    count(CASE WHEN attr1 > 20 THEN 1 END),
FROM
   table1 t1
   JOIN table2 t2
     ON t1.o_id = t2.o_id
GROUP BY
   t1.dt
;

COUNT()聚合函数计算参数表达式不是NULL的每个组中的行数。只有满足({1}} CASE条件时,才会计算的WHEN个表达式为非空。

答案 1 :(得分:2)

问题是你没有加入子查询中的表,但无论如何这个查询可以作为一个条件聚合完成,至少我认为看起来好一点:

SELECT
    t1.dt,
    SUM(CASE WHEN attr1 BETWEEN 0 AND 10 THEN 1 ELSE 0 END) AS "count(0-10)",
    SUM(CASE WHEN attr1 BETWEEN 11 AND 20 THEN 1 ELSE 0 END) AS "count(11-20)",
    SUM(CASE WHEN attr1 > 21 THEN 1 ELSE 0 END) AS "count(21+)"
FROM
   table1 t1
JOIN
   table2 t2
ON
   t1.o_id = t2.o_id
GROUP BY
   t1.dt;

答案 2 :(得分:1)

SELECT
t1.dt
,(select count(tt2.o_id) from table1 tt1, table2 tt2 WHERE attr1 BETWEEN  0 AND 10 AND t1.o_id=t2,o_id)
,(select count(tt2.o_id) from table1 tt1, table2 tt2 WHERE attr1 BETWEEN 11 AND 20 AND t1.o_id=t2,o_id)
,(select count(tt2.o_id) from table1 tt1, table2 tt2 WHERE attr1 > 21 AND t1.o_id=t2,o_id)
FROM table1 t1, table2 t2 
WHERE t1.o_id = t2.o_id 
GROUP BY t1.dt;

答案 3 :(得分:1)

这可以使用SUM(CASE)来完成:

SELECT
    t1.dt,
    count(case when attr1 BETWEEN  0 AND 10 then tt2.o_id end),
    count(case when attr1 BETWEEN 11 AND 20 thent t2.o_id end),
    count(case when attr1 > 21              thent t2.o_id end)
FROM
   table1 t1, table2 t2
WHERE
   t1.o_id = t2.o_id
GROUP BY
   t1.dt;