SQL - 如何查找列组合之前是不是发生过?
Posted
技术标签:
【中文标题】SQL - 如何查找列组合之前是不是发生过?【英文标题】:SQL - How to find if the combination of column has occured before or not?SQL - 如何查找列组合之前是否发生过? 【发布时间】:2021-06-20 07:35:27 【问题描述】:下面的例子演示了这个问题
id | location | dt |
---|---|---|
1 | India | 2020-01-01 |
2 | Usa | 2020-02-01 |
1 | Usa | 2020-03-01 |
3 | China | 2020-04-01 |
1 | India | 2020-05-01 |
2 | France | 2020-06-01 |
1 | India | 2020-07-01 |
2 | Usa | 2020-08-01 |
此表按日期排序。 我想创建另一个列,它会告诉 id 是否曾经到过该位置。
所以,输出会是这样的
id | location | dt | travelled |
---|---|---|---|
1 | India | 2020-01-01 | 0 |
2 | Usa | 2020-02-01 | 0 |
1 | Usa | 2020-03-01 | 0 |
3 | China | 2020-04-01 | 0 |
1 | India | 2020-05-01 | 1 |
2 | France. | 2020-06-01 | 0 |
1 | India | 2020-07-01 | 1 |
2 | Usa | 2020-08-01 | 1 |
我面临的问题是,对于每一行,我只需要考虑它上面的行。
【问题讨论】:
是什么阻止了你? 对于任何行,我只需要考虑它上面的行。这是我无法修复的部分 它上面的那一行是什么?这些行有数字吗? 表也有一个日期列。因此,要查看 id 之前是否曾到过该位置,我需要考虑上面的行(过去的日期) 【参考方案1】:在CASE
表达式中使用EXISTS
:
SELECT t1.id, t1.location,
CASE
WHEN EXISTS (
SELECT 1
FROM tablename t2
WHERE t2.id = t1.id AND t2.location = t1.location AND t2.date < t1.date
) THEN 1
ELSE 0
END travelled
FROM tablename t1
【讨论】:
EXISTS
产生一个布尔值;你不需要CASE
表达式。
@wildplasser 如果 OP 需要布尔值,则不需要它。如果结果应该是 1 或 0,那么我猜是。【参考方案2】:
我强烈推荐使用窗口函数:
select t.*,
(case when row_number() over (partition by id, location order by date) > 1
then 1 else 0
end) as travelled
from t;
窗口函数通常比其他方法更快。
【讨论】:
以上是关于SQL - 如何查找列组合之前是不是发生过?的主要内容,如果未能解决你的问题,请参考以下文章