问题的标题可能令人困惑,所以我把我的问题写成了文字:
我有一个包含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它消除了具有多条记录的群集中的第一行,这是我不想要的。我怎么解决这个问题?我想过一个小组,但我不知道如何应用这个。
非常感谢!
答案 0 :(得分:1)
编辑:完全更新新要求。这将仅显示与其关联多年的master_id的记录,但是它将显示与该master_id关联的所有记录,即使它们在同一年(参见600 vs 700)。
我们将在cte1中执行你的year_rank,这样我们就可以用cte2中的MAX()函数聚合它来过滤掉max大于你想放在那里的任何变量的位置。然后,我们查询cte1并加入cte2,仅显示与其关联多年的master_id的记录。
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
答案 1 :(得分:0)
我想要消除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
现在我可以将所有这些放入临时表中并删除那些没有显示'的记录。在备注栏中。
你怎么看待这个?有更简单的方法吗?