Mysql 如何在子查询中分组,或者如何实现输出
这是我的疑问:Mysql 如何在子查询中分组,或者如何实现输出,mysql,Mysql,这是我的疑问: SELECT dte,((SELECT COUNT(prdt) as P1 FROM table WHERE prdt LIKE '%P1%' AND stat= 'Done' AND dte BETWEEN '08/01/2016' AND '09/07/2016') as P1, (SELECT COUNT(prdt) as P2 FROM table WHERE prdt LIKE '%P2%' AND stat= 'Done' AND dte BETWEEN '08
SELECT dte,((SELECT COUNT(prdt) as P1 FROM table
WHERE prdt LIKE '%P1%' AND stat= 'Done' AND dte BETWEEN '08/01/2016' AND '09/07/2016') as P1,
(SELECT COUNT(prdt) as P2 FROM table
WHERE prdt LIKE '%P2%' AND stat= 'Done' AND dte BETWEEN '08/01/2016' AND '09/07/2016') as P2,
(SELECT COUNT(prdt) as P3 FROM table
WHERE prdt LIKE '%P3%' AND stat= 'Done' AND dte BETWEEN '08/01/2016' AND '09/07/2016') as P3
FROM table WHERE dte BETWEEN '08/01/2016' AND '09/07/2016' GROUP BY dte
桌子
这就是我想要的输出:
+--------+----+----+----+
| Dte1 | P1 | P2 | P3 |
+--------+----+----+----+
|8/1/2016| 1 |NULL| 1 |
+--------+----+----+----+
|8/2/2016|NULL| 1 |NUll|
+--------+----+----+----+
|8/3/2016| 1 |NULL|NULL|
+--------+----+----+----+
为什么在选择列表中需要子查询?无需多次扫描该表
dte-BETWEEN
谓词中的文本看起来像是DATE
值。但是对于DATE
literals,这些格式无效。如果dte
列是字符串类型(CHAR
或VARCHAR
),并且您正在dte
列中存储日期值。。。你做错了
考虑查询中发生的情况,将dte
(字符串)值'08/15/1999'
作为字符串进行比较。例如,测试此条件:
SELECT '08/15/1999' BETWEEN '08/01/2016' AND '09/16/2016'
评估为真。(就字符串比较而言,这是正确的。但如果我们将这些值视为日期,那么1999年的日期将介于2016年的两个日期之间是没有意义的。)
但是把不确定的日期格式问题放在一边,解决你提出的问题
只需使用条件聚合编写查询。例如:
SELECT t.dte
, SUM( t.stat = 'Done' AND t.prdt LIKE '%P1%' ) AS P1
, SUM( t.stat = 'Done' AND t.prdt LIKE '%P2%' ) AS P2
, SUM( t.stat = 'Done' AND t.prdt LIKE '%P3%' ) AS P3
FROM table t
WHERE t.dte BETWEEN '2016-08-01' AND '2016-09-07'
GROUP BY t.dte
该查询将返回与规范不匹配的“零”计数。为了匹配规范,并返回NULL值代替零,我们可以使用方便的NULLIF
函数将零计数替换为NULL:
SELECT t.dte
, NULLIF(SUM( t.stat = 'Done' AND t.prdt LIKE '%P1%' ),0) AS P1
, NULLIF(SUM( t.stat = 'Done' AND t.prdt LIKE '%P2%' ),0) AS P2
, NULLIF(SUM( t.stat = 'Done' AND t.prdt LIKE '%P3%' ),0) AS P3
FROM table t
WHERE t.dte BETWEEN '2016-08-01' AND '2016-09-07'
GROUP BY t.dte
对于更符合ANSI标准的版本,请替换MySQL速记
NULLIF(SUM( t.stat = 'Done' AND t.prdt LIKE '%P1%' ),0)
与
SUM( CASE WHEN t.stat = 'Done' AND t.prdt LIKE '%P1%' THEN 1 END )
如果有某种(难以理解的)原因需要在选择列表中使用子查询,则可以使用相关子查询。只需从子查询内部的外部查询中引用
dte
的值
SELECT t.dte
, ( SELECT NULLIF(COUNT(*),0)
FROM table t1
WHERE t1.dte = t.dte
AND t1.prdt LIKE '%P1%'
AND t1.stat = 'Done'
) AS P1
, ( SELECT NULLIF(COUNT(*),0)
FROM table t2
WHERE t2.dte = t.dte
AND t2.prdt LIKE '%P2%'
AND t2.stat = 'Done'
) AS P1
, ( SELECT NULLIF(COUNT(*),0)
FROM table t3
WHERE t3.dte = t.dte
AND t3.prdt LIKE '%P3%'
AND t3.stat = 'Done'
) AS P3
FROM table t
WHERE t.dte BETWEEN '2016-08-01' AND '2016-09-07'
GROUP BY t.dte
在选择列表中使用相关子查询通常比使用条件聚合模式更昂贵。这是因为外部查询返回的每一行都会执行子查询。如果外部查询返回一千行,子查询将执行一千次。您应该编辑您的问题并显示您尝试过的内容。我不能按每个选项分组,我可以做些什么来实现我想要的输出?难道没有人会提到房间里的大象吗?什么是“08/01/2016”?那怎么可能是介于两者之间呢?
SELECT t.dte
, ( SELECT NULLIF(COUNT(*),0)
FROM table t1
WHERE t1.dte = t.dte
AND t1.prdt LIKE '%P1%'
AND t1.stat = 'Done'
) AS P1
, ( SELECT NULLIF(COUNT(*),0)
FROM table t2
WHERE t2.dte = t.dte
AND t2.prdt LIKE '%P2%'
AND t2.stat = 'Done'
) AS P1
, ( SELECT NULLIF(COUNT(*),0)
FROM table t3
WHERE t3.dte = t.dte
AND t3.prdt LIKE '%P3%'
AND t3.stat = 'Done'
) AS P3
FROM table t
WHERE t.dte BETWEEN '2016-08-01' AND '2016-09-07'
GROUP BY t.dte