Подсчет количества и суммы на разных уровнях группы в одном запросе Oracle - PullRequest
1 голос
/ 04 ноября 2019

Ниже мой запрос. Есть ли в любом случае использовать разные уровни групповых уровней. Мне нужно получить столбец product_count для подсчета, отличного от Product_id, но не на account_id and acct_type_id level.

В настоящее время столбец product_count имеет значение 1 для каждой строки. Мне просто нужно получить четкое количество идентификаторов продуктов, а также короткие и длинные продажи, агрегированные на уровне account_id,product_id, acct_type_id.

Итак, я хочу, чтобы вывод был таким:

order_date account_id short_sales long_sales **product_count** price product_id acct_type_id <br>
31-Oct-19 6698777      -2800         500           **0**            30       100005      3 <br>
31-Oct-19 6998874      -4000         325           **0**            30       100005      2 <br>
31-Oct-19 5555555      -5000        1000           **0**            30       100005      3 <br>
31-Oct-19 4444444      -1000        5000           **1**            30       100005      2


select POS.ORDER_DATE,
POS.ACCOUNT_ID,
SUM(POS.SHORT_SALES) as SHORT_SALES,
SUM(POS.LONG_SALES) as LONG_SALES,
COUNT(Distinct POS.PRODUCT_ID) AS PRODUCT_COUNT,
POS.PRICE,
POS.PRODUCT_ID,
POS.ACCT_TYPE_ID 
from PRODUCT 

(             
SELECT P.ORDER_DATE, P.ACCOUNT_ID, P.PRODUCT_ID, P.ACCT_TYPE_ID,P.PRICE,case when P.POSITION_SD < 0 THEN P.NET_POSITION_SD END AS SHORT_SALES, 
case when P.POSITION_SD > 0 THEN P.NET_POSITION_SD END AS LONG_SALES 
        FROM PRODUCT P 
        WHERE P.POSITION_DATE = '31-OCT-19'
) POS 
group by POS.ORDER_DATE, POS.ACCOUNT_ID, POS.PRODUCT_ID, POS.ACCT_TYPE_ID,POS.PRICE 
ORDER BY PRODUCT_ID

Ответы [ 2 ]

0 голосов
/ 04 ноября 2019

Я думаю, что это можно исправить, просто переключив COUNT для использования оконного режима.

В этом примере я закомментировал некоторые из ваших запросов, чтобы их было проще воспроизвести, но единственной частью, которую я изменил, был COUNT. строка.

Редактировать: обновлено, чтобы возвращать количество отдельных идентификаторов продукта, только в одной из строк, с остальными значениями product_count, установленными в 0.

-- example data
with product as (select sysdate as order_date, 6698777 as account_id, -1400 as short_sales, 300 as long_sales, 100005 as product_id, 30 as price, 3 as acct_type_id from dual
    union select sysdate, 6698777, -1400, 200, 100005, 30, 3 from dual
    union select sysdate, 5555555, -5000, 1000, 100005, 30, 3 from dual
    union select sysdate, 6998874, -4000, 325, 100005, 30, 2 from dual)
-- query            
select POS.ORDER_DATE,
POS.ACCOUNT_ID,
SUM(POS.SHORT_SALES) as SHORT_SALES,
SUM(POS.LONG_SALES) as LONG_SALES,
count(distinct product_id) over () * case when row_number() over (order by product_id desc) = 1 then 1 else 0 end as product_count, -- changed this line
POS.PRICE,
POS.PRODUCT_ID,
POS.ACCT_TYPE_ID 
from (             
SELECT P.ORDER_DATE, P.ACCOUNT_ID, P.PRODUCT_ID, P.ACCT_TYPE_ID,P.PRICE,
    --case when P.POSITION_SD < 0 THEN P.NET_POSITION_SD END AS 
    SHORT_SALES, 
    --case when P.POSITION_SD > 0 THEN P.NET_POSITION_SD END AS 
    LONG_SALES 
        FROM PRODUCT P 
    --    WHERE P.POSITION_DATE = '31-OCT-19'
) POS 
group by POS.ORDER_DATE, POS.ACCOUNT_ID, POS.PRODUCT_ID, POS.ACCT_TYPE_ID,POS.PRICE 
ORDER BY PRODUCT_ID
0 голосов
/ 04 ноября 2019

Вы можете использовать grouping sets, чтобы определить, для каких столбцов вы вычисляете промежуточные итоги.

Перечислите набор столбцов, для которого требуется промежуточный итог для внутренних скобок:

with products as (
  select mod ( level, 3 ) product_id,
         mod ( level, 6 ) account_id,
         mod ( level, 2 ) acct_type
  from dual
  connect by level <= 10
)
  select product_id, account_id, acct_type, count(*)
  from   products
  group  by grouping sets (
    product_id,
    ( product_id, account_id, acct_type )
  );

PRODUCT_ID     ACCOUNT_ID     ACCT_TYPE     COUNT(*)   
            0             0            0           1 
            0             3            1           2 
            0        <null>       <null>           3 
            1             1            1           2 
            1             4            0           2 
            1        <null>       <null>           4 
            2             2            0           2 
            2             5            1           1 
            2        <null>       <null>           3
...