Sql 在SELECT的结果中包含SELECT未恢复任何数据的行
我正在尝试编写查询以检索以下数据:Sql 在SELECT的结果中包含SELECT未恢复任何数据的行,sql,oracle,Sql,Oracle,我正在尝试编写查询以检索以下数据: TYPE | TOTAL | 0_10 DAYS | 10_20 DAYS | ....... X 300 100 200 ....... Y 0 0 0 ....... Z 600 50
TYPE | TOTAL | 0_10 DAYS | 10_20 DAYS | .......
X 300 100 200 .......
Y 0 0 0 .......
Z 600 50 120 .......
我必须按类型对我的所有条目进行分组,并计算每个日期范围内每种类型的条目数量,并将它们合计起来。
我的问题是需要为我没有检索任何数据的类型显示一行零。基本上,“类型”列始终显示固定数量的类型。到目前为止,我已经尝试过使用“UNION ALL”,但是零行总是会显示出来。我的问题是:
SELECT TYPE AS "ORDERS",
Count(*) AS "TOTAL",
Nvl(Sum(CASE
WHEN ( DATE_ORDER BETWEEN SYSDATE - 10 AND SYSDATE ) THEN 1
ELSE 0
END), 0) AS "0_10_DAYS",
Nvl(Sum(CASE
WHEN ( DATE_ORDER BETWEEN SYSDATE - 20 AND SYSDATE - 11 ) THEN
1
ELSE 0
END), 0) AS "10_20_DAYS",
Nvl(Sum(CASE
WHEN ( DATE_ORDER BETWEEN SYSDATE - 30 AND SYSDATE - 21 ) THEN
1
ELSE 0
END), 0) AS "20_30_DAYS",
Nvl(Sum(CASE
WHEN ( DATE_ORDER <= To_date(SYSDATE - 30) ) THEN 1
ELSE 0
END), 0) AS "PLUS_30_DAYS"
FROM T_ORDERS
WHERE TYPE = 'X'
OR TYPE = 'Y'
OR TYPE = 'Z'
GROUP BY TYPE
UNION ALL
SELECT TYPE AS "ORDERS",
0 AS "TOTAL",
0 AS "0_10_DAYS",
0 AS "10_20_DAYS",
0 AS "20_30_DAYS",
0 AS "PLUS_30_DAYS"
FROM T_ORDERS
WHERE TYPE IS NOT NULL
GROUP BY TYPE;
我是SQL新手,所以如果这个话题上的任何问题的答案都能解决我的问题,请容忍我,但我似乎无法解决它。如果有不清楚的地方,请写在评论框中 试试看:
SELECT TYPE AS "ORDERS",
Count(DATE_ORDER) AS "TOTAL",
Nvl(Sum(CASE
WHEN (DATE_ORDER BETWEEN SYSDATE - 10 AND SYSDATE) THEN 1
ELSE 0
END), 0) AS "0_10_DAYS",
Nvl(Sum(CASE
WHEN (DATE_ORDER BETWEEN SYSDATE - 20 AND SYSDATE - 11) THEN 1
ELSE 0
END), 0) AS "10_20_DAYS",
Nvl(Sum(CASE
WHEN (DATE_ORDER BETWEEN SYSDATE - 30 AND SYSDATE - 21) THEN 1
ELSE 0
END), 0) AS "20_30_DAYS",
Nvl(Sum(CASE
WHEN (DATE_ORDER <= To_date(SYSDATE - 30)) THEN 1
ELSE 0
END), 0) AS "PLUS_30_DAYS"
FROM (SELECT TYPE, DATE_ORDER
FROM T_ORDERS
WHERE TYPE IN ('X', 'Y', 'Z')
UNION ALL
SELECT DECODE(LEVEL, 1,'X', 2,'Y', 3,'Z') TYPE, NULL DATE_ORDER
FROM DUAL
CONNECT BY LEVEL <= 3
) SQ
GROUP BY TYPE
可以使用外部联接来获得所需的结果
with types
AS
(
SELECT 'X' as t_name FROM dual
UNION ALL
SELECT 'Y' as t_name FROM dual
UNION ALL
SELECT 'Z' as t_name FROM dual
)
SELECT
types.t_name AS "ORDERS",
SUM(CASE WHEN T_ORDERS.TYPE IS NULL THEN 0 ELSE 1 END ) AS "TOTAL",
Nvl(Sum(CASE
WHEN ( DATE_ORDER BETWEEN SYSDATE - 10 AND SYSDATE ) THEN 1
ELSE 0
END), 0) AS "0_10_DAYS",
Nvl(Sum(CASE
WHEN ( DATE_ORDER BETWEEN SYSDATE - 20 AND SYSDATE - 11 ) THEN
1
ELSE 0
END), 0) AS "10_20_DAYS",
Nvl(Sum(CASE
WHEN ( DATE_ORDER BETWEEN SYSDATE - 30 AND SYSDATE - 21 ) THEN
1
ELSE 0
END), 0) AS "20_30_DAYS",
Nvl(Sum(CASE
WHEN ( DATE_ORDER <= To_date(SYSDATE - 30) ) THEN 1
ELSE 0
END), 0) AS "PLUS_30_DAYS"
FROM
types
LEFT OUTER JOIN T_ORDERS ON (types.t_name = T_ORDERS.TYPE )
GROUP BY types.t_name
或者,如果类型表中已包含所有类型,则可以使用此表而不是
SELECT
types.t_name AS "ORDERS",
SUM(CASE WHEN T_ORDERS.TYPE IS NULL THEN 0 ELSE 1 END ) AS "TOTAL",
Nvl(Sum(CASE
WHEN ( DATE_ORDER BETWEEN SYSDATE - 10 AND SYSDATE ) THEN 1
ELSE 0
END), 0) AS "0_10_DAYS",
Nvl(Sum(CASE
WHEN ( DATE_ORDER BETWEEN SYSDATE - 20 AND SYSDATE - 11 ) THEN
1
ELSE 0
END), 0) AS "10_20_DAYS",
Nvl(Sum(CASE
WHEN ( DATE_ORDER BETWEEN SYSDATE - 30 AND SYSDATE - 21 ) THEN
1
ELSE 0
END), 0) AS "20_30_DAYS",
Nvl(Sum(CASE
WHEN ( DATE_ORDER <= To_date(SYSDATE - 30) ) THEN 1
ELSE 0
END), 0) AS "PLUS_30_DAYS"
FROM
types
LEFT OUTER JOIN T_ORDERS ON (types.t_name = T_ORDERS.TYPE )
WHERE
types.t_name IN ( 'X', 'Y','Z')
GROUP BY types.t_name
你能提供一些样本数据吗?你的表格设计是错误的。而不是类型|总计| 0|U 10天| 10|U 20天|。。。您应该输入| DAYS_NUM | VAL。然后问题会自行解决。此解决方案不会为没有数据可检索的每种类型显示一行零。@user2629578:请立即尝试。若你们有一个单独的类型值查找表,你们可以用它来代替选择解码…太棒了!我认为它起作用了。我要再测试一下。你能给我简单解释一下你做了什么吗?我对解码和电平有点迷茫。非常感谢@user2629578:如果运行select decode,可能会更清晰一些。。。查询本身-如此处所示:。decode函数是Oracle案例构造的缩写版本-此处的文档:。connect by子句用于生成从1到3的数字列表;这是一个Oracle构造,也可用于生成分层查询-此处的文档:。类型不在类型表中。我已经尝试了您的第一个解决方案,当没有检索到该类型的数据时,它总共显示1。@user2629578:好的,我已经编辑了我的答案。我已经修改了TOTAL列的表达式