Oracle
 sql >> база данни >  >> RDS >> Oracle

Връща нулева стойност, когато не съществуват данни за ред

Първо, напишете отново заявката си. Използвайте изгледи или общ израз на таблица, за да избегнете повторението си три пъти за вашия SELECT , GROUP BY , ORDER 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

Във втория пример можете също да направите без CTE и да използвате вложен SELECT за groups маса. Лесно е да се види как вторият пример е по-лесен за развитие в бъдеще, ако вашите изисквания се променят.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да получите BLOB данни с помощта на oracle ODBC

  2. Грешка на SQL Developer Не може да се намери Java Virtual Machine

  3. как да извлека непрекъснат брой на срещания на стойност на колона в sql?

  4. Стъпка по стъпка R12.2.6 Инсталиране на EBS на Virtual Box Част -2

  5. ORA-24247:достъпът до мрежата е отказан от списъка за контрол на достъпа (ACL) при изпращане на имейл оракул