SQL:对相似数据组使用不同
SQL: Use distinct on groups of similar data
你好朋友我在 Vertica 数据库中遇到以下问题:我有一个很大的 Table
+------+------+------+
| Date | Col1 | Col2 |
+------+------+------+
| 1 | A | B |
| 2 | A | B |
| 3 | D | E |
| 2 | C | D |
| 1 | C | D |
+------+------+------+
如您所见,我有冗余数据,只是在不同的日期(第 1 和 2 行以及第 4 和 5 行)获取的。所以我想要一个 table 通过删除日期较低的行来删除冗余数据,给我这样的结果:
+------+------+------+
| Date | Col1 | Col2 |
+------+------+------+
| 2 | A | B |
| 2 | C | D |
| 3 | D | E |
+------+------+------+
使用 distinct 是行不通的,因为它会随机删除行而不考虑日期,所以我可能会得到这样的 table:
SELECT DISTINCT Col2, Col3 from Table
+------+------+------+
| Date | Col1 | Col2 |
+------+------+------+
| 2 | A | B |
| 1 | C | D |
| 3 | D | E |
+------+------+------+
这是不希望的。
有没有办法做到这一点?
谢谢队友
对您的 2 列执行 GROUP BY
并在最高日期汇总:
SELECT MAX(Date), col1, col2
FROM table
GROUP BY Col1, Col2
如果还有其他你关心的列,可以使用window函数:
select t.*
from (select t.*, max(date) over (partition by col1, col2) as maxd
from t
) t
where date = maxd;
我只是概括了这里的模式并添加了一个,对于所提出的确切问题,这些方法中的任何一种都可能有效,细节决定成败。
@Thomas_G 提出的聚合方法之所以有效,是因为您在分组之外只有 1 列。如果你有两个它可能 mix/match (一些数据来自一行,一些来自另一行)这不太可能是你想要的重复处理策略。
@Gordon_Linoff提出的分析方法很好,但要注意如果日期在源数据中重复,那么你会得到多行,如果它们存在于最大日期。这可能是您想要的,但也可能不是。
另一种方法是只剥掉 window 中的第一行。它将根据您的 window 顺序选择分区中的第一行。如果最多有多个日期,那么您无法保证会选择哪一个,除非您在 window 顺序中包含更多内容。但至少你知道你只会得到一行,这是值得的。
select t.*
from (select t.*, row_number() over (partition by col1, col2 order by date desc) as rn
from t
) t
where rn = 1;
你好朋友我在 Vertica 数据库中遇到以下问题:我有一个很大的 Table
+------+------+------+
| Date | Col1 | Col2 |
+------+------+------+
| 1 | A | B |
| 2 | A | B |
| 3 | D | E |
| 2 | C | D |
| 1 | C | D |
+------+------+------+
如您所见,我有冗余数据,只是在不同的日期(第 1 和 2 行以及第 4 和 5 行)获取的。所以我想要一个 table 通过删除日期较低的行来删除冗余数据,给我这样的结果:
+------+------+------+
| Date | Col1 | Col2 |
+------+------+------+
| 2 | A | B |
| 2 | C | D |
| 3 | D | E |
+------+------+------+
使用 distinct 是行不通的,因为它会随机删除行而不考虑日期,所以我可能会得到这样的 table:
SELECT DISTINCT Col2, Col3 from Table
+------+------+------+
| Date | Col1 | Col2 |
+------+------+------+
| 2 | A | B |
| 1 | C | D |
| 3 | D | E |
+------+------+------+
这是不希望的。
有没有办法做到这一点? 谢谢队友
对您的 2 列执行 GROUP BY
并在最高日期汇总:
SELECT MAX(Date), col1, col2
FROM table
GROUP BY Col1, Col2
如果还有其他你关心的列,可以使用window函数:
select t.*
from (select t.*, max(date) over (partition by col1, col2) as maxd
from t
) t
where date = maxd;
我只是概括了这里的模式并添加了一个,对于所提出的确切问题,这些方法中的任何一种都可能有效,细节决定成败。
@Thomas_G 提出的聚合方法之所以有效,是因为您在分组之外只有 1 列。如果你有两个它可能 mix/match (一些数据来自一行,一些来自另一行)这不太可能是你想要的重复处理策略。
@Gordon_Linoff提出的分析方法很好,但要注意如果日期在源数据中重复,那么你会得到多行,如果它们存在于最大日期。这可能是您想要的,但也可能不是。
另一种方法是只剥掉 window 中的第一行。它将根据您的 window 顺序选择分区中的第一行。如果最多有多个日期,那么您无法保证会选择哪一个,除非您在 window 顺序中包含更多内容。但至少你知道你只会得到一行,这是值得的。
select t.*
from (select t.*, row_number() over (partition by col1, col2 order by date desc) as rn
from t
) t
where rn = 1;