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

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 に答える