sql >> データベース >  >> RDS >> Oracle

行データが存在しない場合はゼロ値を返す

    まず、クエリを書き直します。ビューまたは一般的なテーブル式を使用して、SELECT で 3 回繰り返さないようにします 、 GROUP BYORDER BY 条項。クエリは次のようになります:

    WITH data AS (
        SELECT(CASE WHEN time_dtm > SYSDATE -1 THEN '0-1 day'
                    WHEN time_dtm > SYSDATE -2 AND 
                         time_dtm < SYSDATE -1 THEN '1-2 days'
                    WHEN time_dtm > SYSDATE -3 AND 
                         time_dtm < SYSDATE -2 THEN '2-3 days'
                    WHEN time_dtm > SYSDATE -4 AND 
                         time_dtm < SYSDATE -3 THEN '3-4 days'
                    WHEN time_dtm > SYSDATE -5 AND 
                         time_dtm < SYSDATE -4 THEN 'Closed'
               END) AS Age 
        FROM table_1 
        WHERE id IN (1,2,3)
    )
    SELECT Age, COUNT(*)
    FROM data
    GROUP BY Age
    ORDER BY Age
    

    次に、目的のグループのいずれかが結果で確実に利用できるようにするために、多くのオプションがあります。

    UNION ALL を使用できます :

    WITH data AS (
        SELECT(CASE WHEN time_dtm > SYSDATE -1 THEN '0-1 day'
                    WHEN time_dtm > SYSDATE -2 AND 
                         time_dtm < SYSDATE -1 THEN '1-2 days'
                    WHEN time_dtm > SYSDATE -3 AND 
                         time_dtm < SYSDATE -2 THEN '2-3 days'
                    WHEN time_dtm > SYSDATE -4 AND 
                         time_dtm < SYSDATE -3 THEN '3-4 days'
                    WHEN time_dtm > SYSDATE -5 AND 
                         time_dtm < SYSDATE -4 THEN 'Closed'
               END) AS Age 
        FROM table_1 
        WHERE id IN (1,2,3)
    
        -- The below will add one record for every desired Age group
        UNION ALL
        SELECT '0-1 day'  FROM DUAL UNION ALL
        SELECT '1-2 days' FROM DUAL UNION ALL
        SELECT '2-3 days' FROM DUAL UNION ALL
        SELECT '3-4 days' FROM DUAL UNION ALL
        SELECT 'Closed'   FROM DUAL
    )
    SELECT Age, COUNT(*) - 1 -- Subtract the extra record again
    FROM data
    GROUP BY Age
    ORDER BY Age
    

    LEFT OUTER JOINs を含むまったく別の解決策 :

    -- Groups is a dynamic table that contains the date ranges and their "Age" label
    WITH groups AS (
        SELECT SYSDATE -1 lower, SYSDATE upper, '0-1 day'  Age FROM DUAL UNION ALL
        SELECT SYSDATE -2      , SYSDATE -1   , '1-2 days'     FROM DUAL UNION ALL
        SELECT SYSDATE -3      , SYSDATE -2   , '2-3 days'     FROM DUAL UNION ALL
        SELECT SYSDATE -4      , SYSDATE -3   , '3-4 days'     FROM DUAL UNION ALL
        SELECT SYSDATE -5      , SYSDATE -4   , 'Closed'       FROM DUAL
    )
    SELECT g.Age, NVL(SUM(t.counter), 0)
    FROM groups g
    
    -- LEFT OUTER JOINing "table_1" to "groups" will ensure that every group
    -- appears at least once in the result
    LEFT OUTER JOIN (
      SELECT 1 counter, t.* FROM table_1 t WHERE t.id IN (1,2,3)
    ) t
    ON  t.time_dtm >= g.lower
    AND t.time_dtm <  g.upper
    GROUP BY g.Age
    ORDER BY g.Age
    

    2 番目の例では、CTE を使用せずに、ネストされた SELECT を groups に使用することもできます。 テーブル。要件が変更された場合に、2 番目の例が将来どのように進化しやすいかは容易にわかります。




    1. 個々の行ごとに複数の「where」句を使用して複数の行を更新します

    2. SQL2008に対してSQLスクリプトの互換性を確認する方法

    3. プロセスの終了とキャンセルの違い

    4. フルAzureポータルのClearDBMySQLデータベースはどこにありますか?