运行计数与列不同 - Oracle SQL

时间:2018-04-16 02:50:22

标签: sql oracle running-total cumulative-sum

我想根据CLIENT_ID的运行不同计数来聚合DAYS列,但不应计算从前一天看到的捕获CLIENT_ID。如何在Oracle SQL中执行此操作?

根据下表(让我们调用此表DAY_CLIENT):

DAY CLIENT_ID

1   10
1   11
1   12 
2   10
2   11
3   10
3   11
3   12
3   13
4   10

我想得到(让我们称这个表DAY_AGG):

DAYS CNT_CLIENT_ID

1    3
2    3
3    4
4    4

因此,在第1天,有3个不同的客户端ID。 在第2天,仍有3个因为CLIENT_ID 10&在第1天已经找到11个。在第3天,不同的客户变为4,因为前几天没有找到CLIENT_ID 13。

4 个答案:

答案 0 :(得分:1)

这是一种替代解决方案,可能会或可能不会比其他解决方案更高效:

WITH your_table AS (SELECT 1 DAY, 10 CLIENT_ID FROM dual UNION ALL
                    SELECT 1 DAY, 11 CLIENT_ID FROM dual UNION ALL
                    SELECT 1 DAY, 12 CLIENT_ID FROM dual UNION ALL
                    SELECT 2 DAY, 10 CLIENT_ID FROM dual UNION ALL
                    SELECT 2 DAY, 11 CLIENT_ID FROM dual UNION ALL
                    SELECT 3 DAY, 10 CLIENT_ID FROM dual UNION ALL
                    SELECT 3 DAY, 11 CLIENT_ID FROM dual UNION ALL
                    SELECT 3 DAY, 12 CLIENT_ID FROM dual UNION ALL
                    SELECT 3 DAY, 13 CLIENT_ID FROM dual UNION ALL
                    SELECT 4 DAY, 10 CLIENT_ID FROM dual)
SELECT DISTINCT DAY,
                COUNT(CASE WHEN rn = 1 THEN client_id END) OVER (ORDER BY DAY) num_distinct_client_ids
FROM   (SELECT DAY,
               client_id,
               row_number() OVER (PARTITION BY client_id ORDER BY DAY) rn
        FROM   your_table);

       DAY NUM_DISTINCT_CLIENT_IDS
---------- -----------------------
         1                       3
         2                       3
         3                       4
         4                       4

我建议您针对您的数据测试所有解决方案,看看哪种解决方案最适合您。

答案 1 :(得分:0)

一种方法使用了相关子查询:

SELECT DISTINCT
    d1.DAYS,
    (SELECT COUNT(DISTINCT d2.CLIENT_ID) FROM yourTable d2
     WHERE d2.DAYS <= d1.DAYS) AS CNT_CLIENT_ID
FROM yourTable d1

以下是SQL Server的演示,但它也应该在您的Oracle上运行。我一直在努力设置Oracle演示。

Demo

答案 2 :(得分:0)

如果apply支持,您还可以使用oracle运算符。

select day, CNT_CLIENT_ID  
from DAY_CLIENT t cross apply (
    select count(distinct CLIENT_ID) as CNT_CLIENT_ID
    from DAY_CLIENT
    where day <= t.day) tt 
group by day, CNT_CLIENT_ID; 

以其他方式使用subquerycorrelation方法

select day, (select count(distinct CLIENT_ID) 
             from DAY_CLIENT
             where day <= t.day) as DAY_CLIENT
from DAY_CLIENT t
group by day;

答案 3 :(得分:0)

始终尽量保持简单。如果你想学习其他方法,所有其他答案也很好。但在这种情况下,根本不需要花哨。

SELECT days
     , COUNT(DISTINCT client_id) cnt
FROM
(
 SELECT 1 days, 10 client_id FROM dual --1
 UNION ALL
 SELECT 1, 11 FROM dual --2
 UNION ALL
 SELECT 1, 12 FROM dual --3
 UNION ALL
 SELECT 1, 11 FROM dual --4
 UNION ALL
 SELECT 2, 10 FROM dual
 UNION ALL
 SELECT 2, 11 FROM dual
 UNION ALL
 SELECT 2, 12 FROM dual
 UNION ALL
 SELECT 3, 10 FROM dual
 UNION ALL
 SELECT 3, 11 FROM dual
 UNION ALL
 SELECT 3, 12 FROM dual
 UNION ALL
 SELECT 3, 13 FROM dual
 UNION ALL
 SELECT 4, 10 FROM dual
)
GROUP BY days
ORDER BY 1
/
DAYS | CLIENT_ID
----------------
 1          3
 2          3
 3          4
 4          1
相关问题