计算具有相同ID和日期< = CURDATE()的行

时间:2015-02-15 13:37:35

标签: mysql sql

如何编写一个结合了两个SELECT语句的SQL查询?

我有这张桌子

+-----+--------------+----------------+
| ID  |     DATE     | other props... |
+=====+==============+
|  1  |  2015-01-02  | 
+-----+--------------+
|  1  |  2015-02-03  |
+-----+--------------+
|  2  |  2015-03-16  | 
+-----+--------------+
|  3  |  2015-02-01  | 
+-----+--------------+
|  3  |  2016-05-14  | 
+-----+--------------+

并想要计算

  1. 存在多少具有相同ID的行

  2. 其中有多少行是< =当前日期

  3. 示例结果:

    +-----+-----------------+
    | ID  | COUNT | expired |
    +=====+=================+
    |  1  |   2   |    2    | 
    +-----+-----------------+
    |  2  |   1   |    0    |
    +-----+-----------------+
    |  3  |   2   |    1    |
    +-----+-----------------+
    

    我使用这些查询来完成每项任务:

    计算行数

    SELECT `ID`, COUNT(*) AS `count` 
    FROM `table`
    GROUP BY `ID`
    

    计数已过期

    SELECT `ID`, COUNT(*) AS `expired` 
    FROM `table`
    WHERE `DATE` <= CURDATE(
    GROUP BY `ID`
    

3 个答案:

答案 0 :(得分:2)

您可以使用此查询:

SELECT
  ID,
  COUNT(*) AS cnt,
  SUM(`date`<CURDATE()) AS expired
FROM
  tablename
GROUP BY
  ID

COUNT(*)将计算所有行,而SUM()将仅计算过期行(date<CURDATE()将在日期过期时计算为1,否则将计为0

请查看工作小提琴here

答案 1 :(得分:1)

您可以简单地统计记录和总结:

SELECT
  id,
  count(*),
  sum(date < CURRENT_DATE())
FROM expiration
GROUP BY id;

答案 2 :(得分:1)

我倾向于选择JOIN s作为此类工作的范围:

SELECT id, COUNT(*) AS count, COUNT(expire) AS expired
FROM Ex
LEFT JOIN (SELECT CAST('2015-02-15' AS DATE) AS expire) T
       ON T.expire >= date
GROUP BY id

SQL Fiddle Example
...将产生您正在寻找的结果。显然,在实际代码中替换CURRENT_DATE或参数;此处使用特定值来保留示例结果。

(理论上,这种形式的范围查询可以通过索引扫描/探测来回答,而不需要扫描基础表行。但是,我不确定MySQL是否足够智能以利用这个,或者任何RDBMS ......)