计数独特的+带有条件SQL Oracle的窗口功能

发布于 2025-02-01 22:07:28 字数 1900 浏览 2 评论 0 原文

我有一个数据表如下:

customerId contruct_id value_date
a 1234 01-JUL-20
A 7896 20-DEC-20-DEC-20
C 6578 01-JUN-20
C 8990 C 8990 20-OCT-20-OCT-20
C 4789 20-DEC-21
B 3457 09--3457 09--3457 09--3457 09--3457 09- 9月21日,

我尝试在每个唯一 customeriD 的每个 value_date 之前尝试计算 contract_id 的不同数量。

所需的结果是:

customerId value_date count_contract
a 01-Jul-20 0
A 20-DEC-20 1
C 01-JUN-20 0
C 20-OCT-20 1
C 20-DEC 20-DEC-21 21 2
B 09-SEP-21 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:在此处不允许订购30487。00000-“不允许在此处订购” *原因:不同的功能和比率_to_report不能有订单 *行动:

谢谢大家的答案!!! 我发现一种更好的方式来计算不同的方式,因为同一customerID的几个不同的合同_id具有相同的value_date。

我正在使用等级()

这是我的解决方案:

I have a data table as below:

CustomerID Contract_id Value_date
A 1234 01-JUL-20
A 7896 20-DEC-20
C 6578 01-JUN-20
C 8990 20-OCT-20
C 4789 20-DEC-21
B 3457 09-SEP-21

I tried to count distinct number of Contract_id before each Value_date for each unique CustomerID.

The desired result is:

CustomerID Value_date Count_contract
A 01-JUL-20 0
A 20-DEC-20 1
C 01-JUN-20 0
C 20-OCT-20 1
C 20-DEC-21 2
B 09-SEP-21 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;

but it didn't work with the error:

Error report -
SQL Error: ORA-30487: ORDER BY not allowed here 30487. 00000 - "ORDER BY not allowed here"
*Cause: DISTINCT functions and RATIO_TO_REPORT cannot have an ORDER BY
*Action:

THANK YOU ALL FELLOWS FOR THE ANSWERS!!!
I found a nicer way to count distinct as several different Contract_id of the same CustomerID have same value_date.

I was using rank()

Here is my solution:
https://dbfiddle.uk/?rdbms=oracle_21&fiddle=c145c0432e003c1be52dbe0685c8d259

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

烟柳画桥 2025-02-08 22:07:28

您可以查看给定客户的第一次出现 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:

You can check the first occurrence of the contract_id for a given customer.
Then Count only the first occurrence.

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: Try here

や莫失莫忘 2025-02-08 22:07:28

您的预期结果似乎不需要计数不同的合同_id,如果这是正确的,那么您可以省略在计数中使用不同的使用,而查询将起作用。

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

Your expected result does not appear to require counting distinct contract_id's and if that is true then you could just omit the use of distinct within the count and your query would work.

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
来世叙缘 2025-02-08 22:07:28

这可以使用 Model 子句来完成:

 选择 *
从t
模型
  /*与分析功能相同*/
  (customer_id)分区
  /*这将用作以后的订购标准*/
  尺寸(DT)
  措施(
    /*需要指定所有列
      不在分区或尺寸中*/
    contract_id,
    0作为CNT
  )
  规则(
    cnt [任何] =
      /*dt&lt; = cv(dt)是所有日期
      当前值日期。
      与窗口规格相同*/
      count(DISTCONT_ID)[DT&LT; = CV(DT)]
  )
 
 customer_id | DT | Contract_id | CNT
:----------- | :-------- | -----------:| - :
A | 01-JUL-20 | 1234 | 1
A | 20-Dec-20 | 7896 | 2
C | 01-Jun-20 | 6578 | 1
C | 20-OCT-20 | 8990 | 2
C | 20-DEC-21 | 4789 | 3
C | 23-dec-21 | 4789 | 3
b | 09-Sep-21 | 3457 | 1

db&lt;&gt;&gt;

:如果多个 Contract_id 每个日期,您可以添加唯一的单个参考,因此模型将不符合重复的维度值。请参阅更新的代码和结果:

 选择 *
从t
模型
  /*与分析功能相同*/
  (customer_id)分区
  /*这将用作以后的订购标准*/
  尺寸(DT)
  措施(
    /*需要指定所有列
      不在分区或尺寸中*/
    contract_id,
    0作为CNT
  )
  独特的单个参考
  规则(
    cnt [任何] =
      /*dt&lt; = cv(dt)是所有日期
      当前值日期。
      与窗口规格相同*/
      count(DISTCONT_ID)[DT&LT; = CV(DT)]
  )
 
 customer_id | DT | Contract_id | CNT
:----------- | :-------- | -----------:| - :
A | 01-JUL-20 | 1234 | 1
A | 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-DEC-21 | 4789 | 4
C | 23-dec-21 | 4789 | 4
b | 09-Sep-21 | 3457 | 1

db&lt;&gt;&gt;

This may be done with a model clause:

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)]
  )
CUSTOMER_ID | DT        | CONTRACT_ID | CNT
:---------- | :-------- | ----------: | --:
A           | 01-JUL-20 |        1234 |   1
A           | 20-DEC-20 |        7896 |   2
C           | 01-JUN-20 |        6578 |   1
C           | 20-OCT-20 |        8990 |   2
C           | 20-DEC-21 |        4789 |   3
C           | 23-DEC-21 |        4789 |   3
B           | 09-SEP-21 |        3457 |   1

db<>fiddle here

UPD: In case of multiple contract_id per date you may add unique single reference, so model will not comply on duplicated dimension values. See updated code and a result:

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)]
  )
CUSTOMER_ID | DT        | CONTRACT_ID | CNT
:---------- | :-------- | ----------: | --:
A           | 01-JUL-20 |        1234 |   1
A           | 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-DEC-21 |        4789 |   4
C           | 23-DEC-21 |        4789 |   4
B           | 09-SEP-21 |        3457 |   1

db<>fiddle here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文