如何使用分析窗口 SQL 函数在同一数据集的多组行中查找 id 值

Posted

技术标签:

【中文标题】如何使用分析窗口 SQL 函数在同一数据集的多组行中查找 id 值【英文标题】:How to lookup id values in groups of rows of the same dataset using analytic window SQL function 【发布时间】:2015-04-26 02:27:21 【问题描述】:
--Dataset Name: Jobs
week   date    job_id
----------------------
wk1    01/15   300
wk1    01/15   301
wk1    01/15   302
wk2    01/22   300 
wk2    01/22   302
wk2    01/22   303
wk2    01/22   304
wk3    01/29   302
wk3    01/29   304
wk3    01/29   305

我有一个像上面这样的数据集。我想创建 3 个额外的列,即:

is_job_id_present_in_wk1

is_job_id_present_in_wk2

is_job_id_present_in_wk3

我想编写一个 SQL 查询,将三个新列中的每一列的每一行标记为 1 或 0。我不想使用自加入。我想利用一些分析窗口函数。

例如,对于给定数据集中的第一行,is_job_id_present_in_wk1、is_job_id_present_in_wk2 和 is_job_id_present_in_wk3 的值为 1(因为 job_id 300 在所有三周中都存在)。

对于给定数据集中的第二行,is_job_id_present_in_wk1 的值为 1,is_job_id_present_in_wk2 为 0,is_job_id_present_in_wk3 为 0(因为 job_id 301 仅在第 1 周出现)。

尝试到现在:

SELECT week, date, job_id
       , CASE WHEN job_id = 
                            FIRST_VALUE(CASE WHEN week='wk1' THEN job_id ELSE NULL END) OVER(ORDER BY job_id rows between current row and current row) 
 THEN 1 ELSE 0 END as is_job_id_present_in_wk1
 FROM jobs;

【问题讨论】:

问题底部的查询结果是什么? 【参考方案1】:

试试:

SELECT week, date, job_id,
        max( case when week = 'wk1' then 1 else 0 end )
            over (partition by  job_id) as is_job_id_present_in_wk1,
        max( case when week = 'wk2' then 1 else 0 end )
            over (partition by job_id) as is_job_id_present_in_wk2,
        max( case when week = 'wk3' then 1 else 0 end )
            over (partition by  job_id) as is_job_id_present_in_wk2
FROM jobs;

也试试这个版本:

SELECT week, date, job_id
       , CASE WHEN EXISTS( SELECT 1 FROM jobs job1 
                           WHERE job1.job_id = jobs.job_id AND job1.week = 'wk1' )
              THEN 1 ELSE 0 END  as is_job_id_present_in_wk1
       , CASE WHEN EXISTS( SELECT 1 FROM jobs job1 
                           WHERE job1.job_id = jobs.job_id AND job1.week = 'wk2' )
              THEN 1 ELSE 0 END  as is_job_id_present_in_wk2
       , CASE WHEN EXISTS( SELECT 1 FROM jobs job1 
                           WHERE job1.job_id = jobs.job_id AND job1.week = 'wk3' )
              THEN 1 ELSE 0 END  as is_job_id_present_in_wk3
 FROM jobs;

因为它可能比具有分析功能的版本更快,尤其是当您在 job_id + week 列上创建复合索引时。

【讨论】:

我已经让第二个解决方案工作了。我只是在等着弄清楚使用窗口函数的逻辑——这是你的第一个解决方案。我应该可以写这个。啊啊。非常感谢

以上是关于如何使用分析窗口 SQL 函数在同一数据集的多组行中查找 id 值的主要内容,如果未能解决你的问题,请参考以下文章

如何使用多组行的数字更新列?

VB中从SQL Server到Excel的海量数据导出

对表格进行排序,但将多组行放在一起

单组学的多变量分析 2.稀疏偏最小二乘判别分析(sPLS-DA)

Spark将多组行过滤为单行

如何使用 Seaborn 并排绘制熊猫数据框的多组列