分区和选择具有多个记录的集群
partitioning and selecting clusters with multiple records
问题的 header 可能令人困惑,所以我把我的问题写成文字:
我有一个 table,带有 master_ids、ID 和年份。 master_id 可以包含不同的 ID。每个 Id 都与一年相关联。我已经按 master_id 划分并给每年一个排名 (year_rank)。
+-----------+----+------+-----------+
| master_id | id | year | year_rank |
+-----------+----+------+-----------+
| 100 | 1 | 2017 | 1 |
| 100 | 2 | 2016 | 2 |
| 100 | 3 | 2015 | 3 |
| 200 | 9 | 2001 | 1 |
| 300 | 5 | 2020 | 1 |
| 300 | 4 | 2010 | 2 |
| 400 | 7 | 1999 | 1 |
| 400 | 11 | 1996 | 2 |
| 500 | 20 | 1999 | 1 |
| 600 | 25 | 2005 | 1 |
| 600 | 29 | 2005 | 1 |
+-----------+----+------+-----------+
我的目标是只选择记录多于 1 的集群来进行比较:
+-----------+----+------+-----------+
| master_id | id | year | year_rank |
+-----------+----+------+-----------+
| 100 | 1 | 2017 | 1 |
| 100 | 2 | 2016 | 2 |
| 100 | 3 | 2015 | 3 |
| 300 | 5 | 2020 | 1 |
| 300 | 4 | 2010 | 2 |
| 400 | 7 | 1999 | 1 |
| 400 | 11 | 1996 | 2 |
+-----------+----+------+-----------+
如果我将 year_rank > 1 放在何处,它会消除具有多个我不想要的记录的簇中的第一行。我该如何解决这个问题?我想到了一个分组依据,但我不知道如何应用它。
非常感谢!
编辑:针对新要求进行了全面更新。这将只显示 master_ids 的记录,这些记录与它们关联了多年,但是它会显示与 master_id 关联的所有记录,即使它们在同一年(参见 600 与 700)。
我们将在 cte1 中执行您的 year_rank,以便我们可以将其与 cte2 中的 MAX() 函数聚合,以过滤掉 max 大于您想要放置在那里的任何变量的地方。然后我们查询 cte1 并加入 cte2 以仅显示 master_ids 的记录,这些记录与它们关联了多年。
WITH cte1 AS (
SELECT
master_id,
id,
year,
RANK() OVER (PARTITION BY master_id ORDER BY year DESC) AS year_rank
FROM tbl
),
cte2 AS (
SELECT
master_id
FROM cte1
GROUP BY master_id
HAVING MAX(year_rank) > 1
)
SELECT
cte1.master_id,
cte1.id,
cte1.year,
cte1.year_rank
FROM cte1
JOIN cte2 ON
cte1.master_id = cte2.master_id
我想办法消除在 master_id:
中没有年份差异的行
select *,
case
when (master_id = (lead(master_id) over (order by master_id))) and
(year = (lead(service_year) over (order by master_id))) then 'no show'
when (master_id = (lag(master_id) over (order by master_id))) and
(year = (lag(service_year) over (order by master_id))) then 'no show'
else ''
end as note
from table
现在我可以将所有这些放入临时 table 并删除注释列中具有 'no show' 的记录。
你怎么看这个?有没有更简单的方法?
问题的 header 可能令人困惑,所以我把我的问题写成文字:
我有一个 table,带有 master_ids、ID 和年份。 master_id 可以包含不同的 ID。每个 Id 都与一年相关联。我已经按 master_id 划分并给每年一个排名 (year_rank)。
+-----------+----+------+-----------+
| master_id | id | year | year_rank |
+-----------+----+------+-----------+
| 100 | 1 | 2017 | 1 |
| 100 | 2 | 2016 | 2 |
| 100 | 3 | 2015 | 3 |
| 200 | 9 | 2001 | 1 |
| 300 | 5 | 2020 | 1 |
| 300 | 4 | 2010 | 2 |
| 400 | 7 | 1999 | 1 |
| 400 | 11 | 1996 | 2 |
| 500 | 20 | 1999 | 1 |
| 600 | 25 | 2005 | 1 |
| 600 | 29 | 2005 | 1 |
+-----------+----+------+-----------+
我的目标是只选择记录多于 1 的集群来进行比较:
+-----------+----+------+-----------+
| master_id | id | year | year_rank |
+-----------+----+------+-----------+
| 100 | 1 | 2017 | 1 |
| 100 | 2 | 2016 | 2 |
| 100 | 3 | 2015 | 3 |
| 300 | 5 | 2020 | 1 |
| 300 | 4 | 2010 | 2 |
| 400 | 7 | 1999 | 1 |
| 400 | 11 | 1996 | 2 |
+-----------+----+------+-----------+
如果我将 year_rank > 1 放在何处,它会消除具有多个我不想要的记录的簇中的第一行。我该如何解决这个问题?我想到了一个分组依据,但我不知道如何应用它。
非常感谢!
编辑:针对新要求进行了全面更新。这将只显示 master_ids 的记录,这些记录与它们关联了多年,但是它会显示与 master_id 关联的所有记录,即使它们在同一年(参见 600 与 700)。
我们将在 cte1 中执行您的 year_rank,以便我们可以将其与 cte2 中的 MAX() 函数聚合,以过滤掉 max 大于您想要放置在那里的任何变量的地方。然后我们查询 cte1 并加入 cte2 以仅显示 master_ids 的记录,这些记录与它们关联了多年。
WITH cte1 AS (
SELECT
master_id,
id,
year,
RANK() OVER (PARTITION BY master_id ORDER BY year DESC) AS year_rank
FROM tbl
),
cte2 AS (
SELECT
master_id
FROM cte1
GROUP BY master_id
HAVING MAX(year_rank) > 1
)
SELECT
cte1.master_id,
cte1.id,
cte1.year,
cte1.year_rank
FROM cte1
JOIN cte2 ON
cte1.master_id = cte2.master_id
我想办法消除在 master_id:
中没有年份差异的行select *,
case
when (master_id = (lead(master_id) over (order by master_id))) and
(year = (lead(service_year) over (order by master_id))) then 'no show'
when (master_id = (lag(master_id) over (order by master_id))) and
(year = (lag(service_year) over (order by master_id))) then 'no show'
else ''
end as note
from table
现在我可以将所有这些放入临时 table 并删除注释列中具有 'no show' 的记录。
你怎么看这个?有没有更简单的方法?