Oracle SQL условная сумма - PullRequest
       89

Oracle SQL условная сумма

3 голосов
/ 30 апреля 2019

У меня есть таблица имен и числовых значений, и я хочу суммировать значения, сгруппированные по именам.Эта часть проста:

SELECT
        name,
        SUM(my_value) "MyValue"
    FROM my_table     
    GROUP BY name

Но у меня также есть строка 'UNLIMITED' в значениях.Когда в группе есть «НЕОГРАНИЧЕННЫЙ», я просто хочу выбрать значение «НЕОГРАНИЧЕННЫЙ» и не делать никаких сумм.Это то, что я придумал, используя UNION, но я знаю, что есть лучший способ:

SELECT 
name, 
MAX("MyValue") 
FROM (
    SELECT
        name,
        'UNLIMITED' "MyValue"
    FROM my_table
    WHERE my_value = 'UNLIMITED' 
    GROUP BY name
    UNION
    SELECT
        name,
        TO_CHAR(SUM(
            CASE WHEN my_value = 'UNLIMITED'
            THEN '0'
            ELSE my_value END
        )) "MyValue"
    FROM my_table     
    GROUP BY name
) t 
GROUP BY name

Пожалуйста, проверьте SqlFiddle для реального примера.

Таблица примеров

NAME    MY_VALUE
name1   50
name1   20
name2   30
name2   UNLIMITED

Пример желаемого результата

NAME    SUM("MYVALUE")
name1   70
name2   UNLIMITED

Ответы [ 3 ]

3 голосов
/ 30 апреля 2019

Это довольно простой способ выразить логику:

SELECT name,
       (CASE WHEN MAX(my_value) = 'UNLIMITED' THEN 'UNLIMITED'
             ELSE TO_CHAR(SUM(CASE WHEN my_value <> 'UNLIMITED' THEN my_value END))
        END)
FROM my_table
GROUP BY name;

При этом используется тот факт, что символы упорядочены после чисел.

Или аналогичная логика:

SELECT name,
       (CASE WHEN COUNT(*) <> COUNT(NULLIF(my_value, 'UNLIMITED')) THEN 'UNLIMITED'
             ELSE TO_CHAR(SUM(NULLIF(my_value, 'UNLIMITED')))
        END)
FROM my_table
GROUP BY name;
2 голосов
/ 30 апреля 2019

Один из способов сделать это с помощью оконных функций.

SELECT DISTINCT
    name,        
    CASE WHEN sum(case when my_value = 'UNLIMITED' then 1 else 0 end) over(partition by name) >= 1
    THEN 'UNLIMITED'
    ELSE cast(sum(case when my_value = 'UNLIMITED' then 0 else cast(my_value as number) end) over(partition by name)
              as varchar(255))
    end as myval
FROM my_table
0 голосов
/ 30 апреля 2019

Это работает

create  table tempxx (a nvarchar2(10), b nvarchar2(20))
insert into tempxx values ('a', 50);
insert into tempxx values ('a', 20);
insert into tempxx values ('b', 30);
insert into tempxx values ('b', 'UNLIMITED');


SELECT allt.a, decode(ut.max, NULL, to_char(allt.sum), to_char(ut.max)) as val
From
((SELECT
    a,
    sum(decode(b, 'UNLIMITED', 0, b)) sum
FROM tempxx 
Group by a) allT left join 
(SELECT
    a,
   Max(b) max
FROM tempxx 
WHERE  b = 'UNLIMITED'  
Group by a) ut on allt.a = ut.a)

A VAL
------------
b UNLIMITED
a 70

В основном, выберите все строки слева и объедините их только без ограничений.Если неограниченная запись равна нулю, оставьте одну, в противном случае возьмите неограниченные данные

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...