在 Sqlite 中,为不同列中返回的每个名称获取前 2 个
Posted
技术标签:
【中文标题】在 Sqlite 中,为不同列中返回的每个名称获取前 2 个【英文标题】:In Sqlite get top 2 for each name returned in different columns 【发布时间】:2020-11-14 18:48:16 【问题描述】:我有这个返回按 Hipaa_Short 分组的最近 2 个日期。对于每个 Hipaa_Short,我想要一个列中的最新消息和另一列中的第二个最新消息。有可能缺少日期(因此 Hipaa_Short 只有一行)在这种情况下,我也希望显示空值。我正在使用 Sqlite3,所以我确信一些“花哨”的东西不会起作用。
SELECT * FROM
(
SELECT *, ROW_NUMBER() OVER (PARTITION BY Hipaa_Short ORDER BY Meeting_Date DESC) AS rn
FROM Meetings
)
WHERE rn < 3
这是我得到的,但不是我想要的:
pk_id Hipaa_Short Meeting_Date rn
+-------|-------------|--------------+-----+
| 2 | LastFirst | 2020-02-01 | 2 |
| 5 | LastFirst | 2020-03-01 | 1 |
| 6 | JoneBob | 2020-03-01 | 2 |
| 7 | JoneBob | 2020-04-01 | 1 |
| 8 | JonesTom | 2020-06-01 | 2 |
| 9 | JonesTom | 2020-07-01 | 1 |
| 10 | NortEdw | 2020-04-01 | 1 |
+-------|-------------|--------------+-----+
会议桌:
REATE TABLE "Meetings" (
"id_pk" INTEGER NOT NULL,
"Hipaa_Short" TEXT NOT NULL,
"Meeting_Date" TEXT NOT NULL,
"MTG_Year" INTEGER,
"MTG_Month" INTEGER,
"MTG_Day" INTEGER,
"CN_Date" TEXT,
"Meeting_Type" TEXT,
"Date_Added" TEXT,
"Annual" TEXT,
"LOCSI_Flag" TEXT,
"Hipaa_RID" TEXT,
PRIMARY KEY("id_pk"),
UNIQUE("Hipaa_Short","Meeting_Date")
)
样本数据:
pk_id Hipaa_Short Meeting_Date
+-------|-------------|--------------+
| 1 | LastFirst | 2020-01-01 |
| 2 | LastFirst | 2020-02-01 |
| 3 | JoneBob | 2020-02-01 |
| 4 | JonesTom | 2020-02-01 |
| 5 | LastFirst | 2020-03-01 |
| 6 | JoneBob | 2020-03-01 |
| 7 | JoneBob | 2020-04-01 |
| 8 | JonesTom | 2020-06-01 |
| 9 | JonesTom | 2020-07-01 |
| 10 | NortEdw | 2020-04-01 |
+-------|-------------|--------------+
期望的输出:
Hipaa_Short Prior Date Next Date
+-------------|------------+------------+
| LastFirst | 2020-02-01 | 2020-03-01 |
| JoneBob | 2020-03-01 | 2020-04-01 |
| JonesTom | 2020-06-01 | 2020-07-01 |
| NortEdw | | 2020-04-01 |
+-------------|------------|------------+
【问题讨论】:
【参考方案1】:您可以在现有查询之上使用条件聚合来透视结果集:
select
hipaa_short,
max(case when rn = 2 then meeting_date end) prior_date,
max(case when rn = 1 then meeting_date end) next_date,
from (
select
m.*,
row_number() over (partition by hipaa_short order by meeting_date desc) as rn
from meetings m
) m
where rn <= 2
group by hipaa_short
【讨论】:
【参考方案2】:GMB 对这个特定问题的回答略短一点:
select hipaa_short, min(meeting_date) as prior_date, max(meeting_date) as next_date
from (select m.*,
row_number() over (partition by hipaa_short order by meeting_date desc) as rn
from meetings m
) m
where rn <= 2
group by hipaa_short
【讨论】:
【参考方案3】:由于您已经需要对分区进行排序以获得第一个分区,因此使用 lead()
窗口函数可以轻松(并且更有效)将两个日期放在一行中,而无需额外聚合:
WITH cte AS
(SELECT Hippa_Short
, lead(Meeting_Date) OVER w AS "Prior Date"
, Meeting_Date AS "Next Date"
, row_number() OVER w AS rn
FROM meetings
WINDOW w AS (PARTITION BY Hippa_Short ORDER BY Meeting_Date DESC))
SELECT Hippa_Short, "Prior Date", "Next Date"
FROM cte
WHERE rn = 1;
给予
Hippa_Short Prior Date Next Date
----------- ---------- ----------
JoneBob 2020-03-01 2020-04-01
JonesTom 2020-06-01 2020-07-01
LastFirst 2020-02-01 2020-03-01
NortEdw 2020-04-01
【讨论】:
以上是关于在 Sqlite 中,为不同列中返回的每个名称获取前 2 个的主要内容,如果未能解决你的问题,请参考以下文章