简体   繁体   English

count(distinct)over(partition by ...在Oracle SQL中不起作用

[英]count(distinct) over (partition by… doesn't work in Oracle SQL

在此输入图像描述

I want to count the distinct day_number over the past 30 days. 我想计算过去30天的distinct day_number However, the distinct function can't be used with over 但是,不同的功能不能与over一起使用

If I delete distinct , it will give me the total count of the day_number , but day_number can have lots of duplicate. 如果我删除distinct ,它会给我day_number的总数,但是day_number可以有很多重复。 So that's why I want to add distinct . 所以这就是为什么我要添加distinct

select tr.*,
       count( distinct day_number) OVER (PARTITION BY ACCOUNT ORDER BY DAY_number range 29 PRECEDING) as result
from table tr;

Can anyone please show me how to count the distinct numbers in the over(partition by..) statement? 任何人都可以告诉我如何计算over(partition by..)语句中的不同数字? Thanks in advance. 提前致谢。

You can do this by first creating a column that only lists each id once, and then doing a range-count on that column, eg: 您可以通过首先创建一个列,该列仅列出每个id一次,然后对该列执行范围计数,例如:

WITH sd AS (SELECT 1 ID, 10 val FROM dual UNION ALL
            SELECT 1 ID, 20 val FROM dual UNION ALL
            SELECT 2 ID, 30 val FROM dual UNION ALL
            SELECT 2 ID, 40 val FROM dual UNION ALL
            SELECT 4 ID, 50 val FROM dual UNION ALL
            SELECT 4 ID, 60 val FROM dual UNION ALL
            SELECT 6 ID, 70 val FROM dual)
SELECT ID,
       val,
       COUNT(id_distinct) OVER (ORDER BY ID RANGE 3 PRECEDING) cnt_disinct_ids
FROM   (SELECT ID,
               val,
               CASE WHEN row_number() OVER (PARTITION BY ID ORDER BY val) = 1 THEN ID END id_distinct
        FROM   sd);

        ID        VAL CNT_DISINCT_IDS
---------- ---------- ---------------
         1         10               1
         1         20               1
         2         30               2
         2         40               2
         4         50               3
         4         60               3
         6         70               2

ETA: proof that the above technique works for your data: ETA:证明上述技术适用于您的数据:

WITH your_table AS (SELECT 'ABCDE' account_sk, 23 day_sk FROM dual UNION ALL
                    SELECT 'ABCDE' account_sk, 23 day_sk FROM dual UNION ALL
                    SELECT 'ABCDE' account_sk, 24 day_sk FROM dual UNION ALL
                    SELECT 'ABCDE' account_sk, 25 day_sk FROM dual UNION ALL
                    SELECT 'ABCDE' account_sk, 53 day_sk FROM dual UNION ALL
                    SELECT 'ABCDE' account_sk, 53 day_sk FROM dual UNION ALL
                    SELECT 'ABCDE' account_sk, 55 day_sk FROM dual UNION ALL
                    SELECT 'VWXYZ' account_sk, 10 day_sk FROM dual UNION ALL
                    SELECT 'VWXYZ' account_sk, 12 day_sk FROM dual UNION ALL
                    SELECT 'VWXYZ' account_sk, 40 day_sk FROM dual UNION ALL
                    SELECT 'VWXYZ' account_sk, 40 day_sk FROM dual)
SELECT account_sk,
       day_sk,
       COUNT(day_sk_distinct) OVER (PARTITION BY account_sk ORDER BY day_sk RANGE BETWEEN 29 PRECEDING AND CURRENT ROW) count_distinct_day_sk
FROM   (SELECT account_sk,
               day_sk,
               CASE WHEN row_number() OVER (PARTITION BY account_sk, day_sk ORDER BY day_sk) = 1 THEN day_sk END day_sk_distinct
        FROM   your_table);

ACCOUNT_SK     DAY_SK COUNT_DISTINCT_DAY_SK
---------- ---------- ---------------------
ABCDE              23                     1
ABCDE              23                     1
ABCDE              24                     2
ABCDE              25                     3
ABCDE              53                     3
ABCDE              53                     3
ABCDE              55                     2
VWXYZ              10                     1
VWXYZ              12                     2
VWXYZ              40                     2
VWXYZ              40                     2

The count(distinct ...) works fine with the over clause, the main problem it's the order by. count(distinct ...)适用于over子句,主要问题是order by。 You can't do count (distinct ..) over (partition by ... order by ...) because DISTINCT functions and RATIO_TO_REPORT cannot have an ORDER BY. 你不能count (distinct ..) over (partition by ... order by ...)因为DISTINCT函数和RATIO_TO_REPORT不能有ORDER BY。 So i did this: 所以我这样做了:

select tr.*, count (distinct day_number) over (partition by account)
from (select t.*, row_number() over (partition by account order by day_number) row_number from table t) tr
where row_number < 30;

I've tested it in employees scheme of HR (Free oracle scheme that you can find everywhere) I'm not sure it will works in your schema because i have not a replica of it, but, if not, it should give you some ideas: 我已经在HR的员工计划中测试了它(你可以在任何地方找到免费oracle方案)我不确定它会在你的架构中有效,因为我没有它的副本,但是,如果没有,它应该给你一些思路:

 select count (distinct manager_id) over (partition by department_id), department_id, manager_id
from (select e.*, row_number() over (partition by department_id order by employee_id) row_number from employees e)
where row_number < 30;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM