[英]Group by query in snowflake
I have a Snowflake table like the following one:我有一个像下面这样的雪花表:
And I wanted to get for each distinct combination "COMPANY"-"BUSINESS UNIT"-"APPROVER LEVEL", the entry with the most recent data (In case we have more than one entry with most recent date it should return all the entries).我想为每个不同的组合“COMPANY”-“BUSINESS UNIT”-“APPROVER LEVEL”获取具有最新数据的条目(如果我们有多个具有最新日期的条目,它应该返回所有条目) . Thus, considering the table of the example above, it would return the following:因此,考虑到上面示例的表格,它将返回以下内容:
What is the SQL query I have to write in Snowflake order to obtain this?我必须以 Snowflake 顺序编写的 SQL 查询是什么?
So very similar to Brandon's answer use QUALIFY :与 Brandon 的回答非常相似,请使用QUALIFY :
But given you want first ranking items, useRANK (which is the same is DENSE_RANK that Phil mentions)但是如果你想要排名第一的项目,请使用RANK (这与 Phil 提到的DENSE_RANK相同)
A CTE for the data (I have used NUMBERS for the valid date, but TEXT would also sort just fine, or converting to DATE also would work the same):数据的 CTE(我使用 NUMBERS 作为有效日期,但 TEXT 也可以很好地排序,或者转换为 DATE 也可以同样工作):
WITH sample_data as (
SELECT * FROM VALUES
('c1', 'but1', 'l1', 20220406, 'Mr. 0', 'id0' ),
('c1', 'but1', 'l1', 20220406, 'Mr. 1', 'id2' ),
('c1', 'but1', 'l1', 20220212, 'Mr. 2', 'id2' ),
('c1', 'but1', 'l1', 20220130, 'Mr. 3', 'id3' ),
('c1', 'but1', 'l2', 20220320, 'Mr. 4', 'id4' ),
('c1', 'but1', 'l2', 20220115, 'Mr. 5', 'id5' ),
('c1', 'but1', 'l2', 20220102, 'Mr. 6', 'id6' )
t(company, business_unit, approver_level, valid_from, approver_name, approver_id)
)
The following SQL以下SQL
SELECT *
FROM sample_data
QUALIFY rank() over(partition by company, business_unit, approvel_level order by valid_from desc ) = 1;
gives:给出:
COMPANY公司 | BUSINESS_UNIT BUSINESS_UNIT 单位 | APPROVER_LEVEL APPROVER_LEVEL | VALID_FROM VALID_FROM | APPROVER_NAME APPROVER_NAME | APPROVER_ID批准者编号 |
---|---|---|---|---|---|
c1 c1 | but1但是1 | l1 l1 | 20220406 20220406 | Mr. 0 0先生 | id0 id0 |
c1 c1 | but1但是1 | l1 l1 | 20220406 20220406 | Mr. 1 1先生 | id2 id2 |
c1 c1 | but1但是1 | l2 l2 | 20220320 20220320 | Mr. 4 4先生 | id4 id4 |
And if your database is not Snowflake (as you have tagged the issue) and does not have QUALIFY here is the way to do this pattern:如果您的数据库不是 Snowflake(因为您已经标记了问题)并且没有 QUALIFY 这里是执行此模式的方法:
WITH smaple_data as (
SELECT * FROM VALUES
('c1', 'but1', 'l1', 20220406, 'Mr. 0', 'id0' ),
('c1', 'but1', 'l1', 20220406, 'Mr. 1', 'id2' ),
('c1', 'but1', 'l1', 20220212, 'Mr. 2', 'id2' ),
('c1', 'but1', 'l1', 20220130, 'Mr. 3', 'id3' ),
('c1', 'but1', 'l2', 20220320, 'Mr. 4', 'id4' ),
('c1', 'but1', 'l2', 20220115, 'Mr. 5', 'id5' ),
('c1', 'but1', 'l2', 20220102, 'Mr. 6', 'id6' )
t(company, business_unit, approver_level,
valid_from, approver_name, approver_id)
)
SELECT company, business_unit,
approver_level, valid_from,
approver_name, approver_id
FROM (
SELECT company, business_unit,
approver_level, valid_from,
approver_name, approver_id,
DENSE_RANK() OVER (PARTITION BY COMPANY, BUSINESS_UNIT, APPROVER_LEVEL
ORDER BY VALID_FROM DESC) as dr
FROM smaple_data
)
WHERE dr = 1
ORDER BY 1,2,3;
You could utilize Qualify to handle this.您可以利用 Qualify 来处理这个问题。 To do so, something like this should work为此,这样的事情应该可行
SELECT *
FROM table_a
QUALIFY ROW_NUMBER() OVER (PARTITION BY COMPANY, BUSINESS_UNIT, APPROVER_LEVEL
ORDER BY VALID_FROM DESC) = 1
;
The main idea is same as suggested by @Brandon Coleman, just need to tweek a bit.主要思想与@Brandon Coleman 所建议的相同,只需要稍微调整一下。
with cte as
(
select max(rn) max_rn from (
select rank() over (partition by company,bu,appr_lvl
order by valid_from) rn
from your_table_name)
)
select *,rank() over (partition by company,bu,appr_lvl
order by valid_from) rn
from your_table_name,cte
qualify rn>=cte.max_rn;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.