简体   繁体   English

在雪花中按查询分组

[英]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.

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