如何编写一个结合了两个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 |
+-----+--------------+
并想要计算
存在多少具有相同ID的行
其中有多少行是< =当前日期
示例结果:
+-----+-----------------+
| 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`
答案 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 ......)