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;