【问题标题】:Count Distinct and Sum at different group levels in single Oracle query在单个 Oracle 查询中计算不同组级别的 Distinct 和 Sum
【发布时间】:2019-11-04 14:24:31
【问题描述】:

以下是我的查询。无论如何要使用不同级别的组级别。我需要获取 product_count 列来计算 Product_id 的不同,但不是 account_id and acct_type_id level

目前 product_count 列每行都为 1。我只需要获得不同数量的产品 ID,并且需要在 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

【问题讨论】:

    标签: sql oracle count grouping distinct


    【解决方案1】:

    您可以使用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
    

    【讨论】:

    • 非常感谢您回答我的问题。根据您的示例,我正在寻找 product_id count = 3 的总数。正如我看到的 3 个独特的 product_ids:0,1,2。所以我只需要 3 的唯一计数,但是我得到每一行的计数。
    【解决方案2】:

    我认为您只需将 COUNT 切换为使用窗口即可解决此问题。

    对于这个例子,我注释掉了你的一些查询,以便更容易重现,但我唯一更改的部分是 COUNT 行。

    编辑:更新后仅返回其中一行中不同产品 ID 的计数,其余的 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
    

    【讨论】:

    • 感谢您回复我的询问。但是我正在从所有 3 行中寻找 1 个总数 - 作为产品计数,因为只有一个具有 100005 的唯一产品 ID。当我尝试这个时 - 我得到了 3 个(这是总行数) - 我想找到唯一的产品ids - Product_Count 的总数为 1。例如:PRODUCT_COUNT, PRODUCT_ID, ACCOUNT_ID 0,1000005, 5555555
      0,1000005, 6698777
      1, 1000005, 6998874
    • 我觉得我读得太快了。因此,您希望所有 PRODUCT_COUNT 行都为零,除了在整个查询结果集中包含不同数量的产品 ID 的行?我编辑了答案以显示该选项。
    猜你喜欢
    • 2023-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-10
    • 1970-01-01
    • 2022-01-24
    • 2013-03-08
    相关资源
    最近更新 更多