0

我正在尝试编写一个查询来检索以下数据:

 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 新手,所以如果关于这个主题的任何问题的答案都能解决我的问题,但我似乎无法解决,请多多包涵。如果有不清楚的地方,请在评论框中写下。

4

2 回答 2

0

尝试:

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 
于 2013-07-30T07:22:14.120 回答
0

您可以使用 OUTER JOIN 来获得所需的结果

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 

或者如果您已经在 TYPES 表中拥有所有类型,则可以使用此表而不是 WITH

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 
于 2013-07-30T07:50:57.447 回答