簡體   English   中英

帶有條件 SQL Oracle 的 COUNT DISTINCT + WINDOW FUNCTION

[英]COUNT DISTINCT + WINDOW FUNCTION with conditions SQL Oracle

我有一個數據表如下:

客戶ID 合同編號 價值日期
一個 1234 20 年 7 月 1 日
一個 7896 20 年 12 月 20 日
C 6578 01-JUN-20
C 8990 20-10-20
C 4789 20-12-21
3457 21 年 9 月 9 日

我試圖在每個唯一CustomerID的每個Value_date之前計算不同數量的Contract_id

期望的結果是:

客戶ID 價值日期 Count_contract
一個 20 年 7 月 1 日 0
一個 20 年 12 月 20 日 1
C 01-JUN-20 0
C 20-10-20 1
C 20-12-21 2
21 年 9 月 9 日 0

Could anyone suggest how I could count distinct in this case?

I tried the window functions:

select distinct CustomerID,
Value_date,
count(distinct Contract_id) over (partition by CustomerID order by Value_date rows unbounded preceding) count_contract
from tbl_cus_contract;

但它不適用於錯誤:

錯誤報告 - SQL 錯誤:ORA-30487: ORDER BY not allowed here 30487. 00000 - “ORDER BY not allowed here” *原因:DISTINCT 函數和 RATIO_TO_REPORT 不能有 ORDER BY *操作:

謝謝大家的回答!!! 我找到了一種更好的方法來計算不同,因為相同 CustomerID 的幾個不同 Contract_id 具有相同的 value_date。

我正在使用rank()

這是我的解決方案: https ://dbfiddle.uk/?rdbms=oracle_21&fiddle=c145c0432e003c1be52dbe0685c8d259

您的預期結果似乎不需要計算不同的contract_id,如果這是真的,那么您可以省略在計數中使用 distinct 並且您的查詢會起作用。

SELECT t1.CustomerID
    , t1.Value_date
    , COUNT(*) OVER (PARTITION BY t1.CustomerID ORDER BY t1.Value_date) - 1
FROM tbl_cus_contract t1
ORDER BY t1.CustomerID
    , t1.Value_date

這可以通過model條款來完成:

 select * from t model /*The same as in analytic function*/ partition by (customer_id) /*This would be used as ordering criteria later*/ dimension by (dt) measures ( /*Need to specify all the columns not in partition or dimension*/ contract_id, 0 as cnt ) rules ( cnt[any] = /*dt <= cv(dt) is all dates before the current value of date. The same as window specification*/ count(distinct contract_id)[dt <= cv(dt)] )
客戶 ID |  DT | 合同 ID | 碳納米管
 :------------ |  :-------- |  ----------: |  --:
一個 |  20 年 7 月 1 日 | 第1234章 1
一個 |  20-DEC-20 |  7896 |  2
 C |  01-JUN-20 |  6578 |  1
 C |  20-OCT-20 |  8990 |  2
 C |  20 年 12 月 21 日 |  4789 |  3
 C |  21 年 12 月 23 日 |  4789 |  3
乙|  09-SEP-21 |  3457 |  1

db<> 在這里擺弄

UPD :如果每個日期有多個contract_id ,您可以添加unique single reference ,因此model將不符合重復的維度值。 查看更新的代碼和結果:

 select * from t model /*The same as in analytic function*/ partition by (customer_id) /*This would be used as ordering criteria later*/ dimension by (dt) measures ( /*Need to specify all the columns not in partition or dimension*/ contract_id, 0 as cnt ) unique single reference rules ( cnt[any] = /*dt <= cv(dt) is all dates before the current value of date. The same as window specification*/ count(distinct contract_id)[dt <= cv(dt)] )
客戶 ID |  DT | 合同 ID | 碳納米管
 :------------ |  :-------- |  ----------: |  --:
一個 |  20 年 7 月 1 日 | 第1234章 1
一個 |  20-DEC-20 |  7896 |  2
 C |  01-JUN-20 |  6578 |  1
 C |  20-OCT-20 |  8990 |  3
 C |  20-OCT-20 |  9999 |  3
 C |  20 年 12 月 21 日 |  4789 |  4
 C |  21 年 12 月 23 日 |  4789 |  4
乙|  09-SEP-21 |  3457 |  1

db<> 在這里擺弄

您可以檢查給定客戶的contract_id的第一次出現。 然后只計算第一次出現。

WITH cte
     AS (SELECT customerid,value_date,contract_id,
                CASE WHEN Row_number() OVER( PARTITION BY customerid, contract_id
                           ORDER BY value_date ) = 1 THEN 1
                END AS first_occurrence_of_contract
         FROM   tbl_cus_contract
)
SELECT customerid,value_date,
       Count(first_occurrence_of_contract)
         OVER (PARTITION BY customerid 
              ORDER BY value_date ROWS unbounded preceding) - 1 AS count_contract
FROM   cte 

db<>fiddle: 在這里試試

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM