具有具有最小值、最大值的 SQL 语句
Posted
技术标签:
【中文标题】具有具有最小值、最大值的 SQL 语句【英文标题】:SQL statement with having, min , max 【发布时间】:2020-01-27 22:21:03 【问题描述】:我有一张桌子:
ID INTEGER NOT NULL, -- AUTOMATIC RECORD'S ID
CUSTOMER_ID INTEGER NOT NULL,
BILING_PERIOD DATE NOT NULL,
DOCUMENT_ID INTEGER NOT NULL,
DATE_CREATED DATE NOT NULL -- WHEN THE DOCUMENT WAS CREATED
我想在计费期间为客户选择文件数量, 为客户在计费期间首先创建的文档的 ID 以及在客户计费期间最后创建的文档的 ID。 所有都应按客户和计费周期分类。 我只需要为客户提供超过 1 个文档的计费周期。
所以当我们有例如这样的数据时:
ID CUSTOMER_ID BILING_PERIOD DOCUMENT_ID DATE_CREATED
1 5 2020-01-01 123 2020-02-01
2 5 2020-01-01 22 2019-02-01
3 5 2020-01-01 3 2010-02-01
4 99 2020-01-01 458 2021-02-01
5 99 2020-01-01 64 2010-02-01
6 100 2020-01-01 120 2020-02-01
7 99 2019-06-01 452 2019-06-01
8 99 2019-06-01 546 2019-12-01
我希望我的结果看起来像这样:
CUSTOMER_ID BILING_PERIOD NR_OF_DOC FIRST_DOC_ID LAST_DOC_ID
5 2020-01-01 3 3 123
99 2019-06-01 2 452 546
99 2020-01-01 2 64 458
我自己只能计算每个用户和期间的文档数
SELECT customer_id, biling_period, count(*) as nr_of_doc
FROM T1
GROUP BY customer_id, biling_period
HAVING COUNT() > 1;
CUSTOMER_ID BILING_PERIOD NR_OF_DOC
5 2020-01-01 3
99 2019-06-01 2
99 2020-01-01 2
我不知道如何获取最新和最旧文档的 document_id。
【问题讨论】:
用您正在使用的数据库标记您的问题。 【参考方案1】:您可以使用row_number()
和聚合:
select
customer_id,
billing_period,
count(*),
max(case when rn_asc = 1 then document_id end) fist_doc_id,
max(case when rn_desc = 1 then document_id end) last_doc_id
from (
select
t.*,
row_number() over(
partition by customer_id, billing_period order by date_created
) rn_asc,
row_number() over(
partition by customer_id, billing_period order by date_created desc
) rn_desc
from t1 t
) t
group by customer_id, billing_period
having count(*) > 1
order by customer_id, billing_period
即使文档 ID 不按顺序,这也会正常工作。
Demo on DB Fiddle:
客户 ID |计费周期 |计数 |拳头文档ID | last_doc_id ----------: | :------------- | ----: | ----------: | ----------: 5 | 2020-01-01 | 3 | 3 | 123 99 | 2019-06-01 | 2 |第452章546 99 | 2020-01-01 | 2 | 64 | 458【讨论】:
很好的解决方案,考虑到customer_id
字段可能有间隙。我自己做了一百次这样的事情,但这个答案似乎是我迄今为止看到的最干净的答案。【参考方案2】:
在您的示例数据中,文档 ID 似乎是按顺序分配的。如果是这种情况,您可以只使用聚合:
SELECT customer_id, billing_period, count(*) as nr_of_doc,
MIN(document_id), MAX(document_id)
FROM T1
GROUP BY customer_id, billing_period
HAVING COUNT() > 1;
【讨论】:
不幸的是,事实并非如此以上是关于具有具有最小值、最大值的 SQL 语句的主要内容,如果未能解决你的问题,请参考以下文章