如何 select 基于多个唯一列的数据而不对结果集中的其余列应用聚合函数
How to select data based on Multiple Unique Columns without applying aggregate functions on rest of columns in resultset
这似乎是重复的,但我找不到符合我要求的答案。参考 here 但不完全相同,答案不适用于我。所以问。
SELECT tab1.col1, tab1.col2, tab1.col3, tab2.col3, tab2.col4
from
(SELECT col1, col2, col3
FROM table1
GROUP BY col1, col2, col3) AS tab1
JOIN tab2
ON tab1.col1 = tab2.col1
AND tab1.col2 = tab2.col2
GROUP BY tab1.col1, tab1.col2, tab1.col3, tab2.col3, tab2.col4
示例数据:
Table1 Tab2
col1 | col2 | col3 col1 | col2 | col3 | col4
======================= =============================
page1 image1 referer1 page1 image1 150 75
page1 image1 referer1 page1 image1 120 85
page2 image2 referer2 page2 image2 200 400
page1 image1 referer1 page1 image1 750 1024
page2 image2 referer2 page2 image2 450 575
page1 image1 referer1 page1 image1 600 900
预期输出:
tab1.col1 | tab1.col2 | tab1.col3 | tab2.col3 | tab2.col4
==================================================================
page1 image1 referer1 600 900
page2 image2 referer2 200 400
这里是最后一组 returns 唯一行,但所有 tab1 列都在重复,这是我不想要的,在这种情况下,记录仅在 tab2.col1 和 tab2.col2 上有所不同。现在的要求是我希望 tab1.col1、tab1.col2、tab1.col3 是唯一的,并且对于来自 tab2 的那些列,只有一对相应的 tab2.col1 和 tab2.col2。 现在我无法从第二组删除 tab2.col1、tab2.col2 并应用最小或最大聚合函数,因为在那种情况下我不会获得映射到 tab2.col2 值的 tab2.col1 值对于特定记录。
注意:我使用 Amazon Redshift 作为数据库。子查询很重要,因为它实际上是从 3 table 连接生成的复杂结果集,如果我将这 3 table 的连接直接与 tab2 结合使用,那么查询将永远运行。为了这个问题的简单起见,假设子查询 returns col1, col2, col3 来自 table1。 Tab2 和 tab1 是巨大的 tables :D... 子查询显着提高了性能(将 20 分钟减少到 ~2 分钟)。
如果以下结果是您的要求,
tab1.col1 | tab1.col2 | tab1.col3 | tab2.col3 | tab2.col4
==================================================================
page1 image1 referer1 120 85
page2 image2 referer2 200 400
然后你可以使用下面的 redshift sql 查询来实现它
SELECT tab1.col1, tab1.col2, tab1.col3, tab2.col3, tab2.col4
FROM
(SELECT col1, col2, col3
FROM table1
GROUP BY col1, col2, col3) AS tab1
JOIN
(SELECT col1, col2, col3, col4
FROM
(SELECT col1, col2, col3, col4, ROW_NUMBER() OVER(PARTITION BY col1, col2 ORDER BY col3 ASC, col4 ASC) row_num
FROM table2) tab2
WHERE row_num = 1) tab2 ON tab1.col1 = tab2.col1
AND tab1.col2 = tab2.col2
上面sql语句中的关键是"ROW_NUMBER() OVER(PARTITION BY col1, col2 ORDER BY col3 ASC, col4 ASC)"。这将为您提供 tab2.col3 的 min 值和 tab2.col4 的 min 值。如果需要max值,则将顺序改为DESC
希望这能解决您的问题。
你也可以查看我写的结果集here
这似乎是重复的,但我找不到符合我要求的答案。参考 here 但不完全相同,答案不适用于我。所以问。
SELECT tab1.col1, tab1.col2, tab1.col3, tab2.col3, tab2.col4
from
(SELECT col1, col2, col3
FROM table1
GROUP BY col1, col2, col3) AS tab1
JOIN tab2
ON tab1.col1 = tab2.col1
AND tab1.col2 = tab2.col2
GROUP BY tab1.col1, tab1.col2, tab1.col3, tab2.col3, tab2.col4
示例数据:
Table1 Tab2
col1 | col2 | col3 col1 | col2 | col3 | col4
======================= =============================
page1 image1 referer1 page1 image1 150 75
page1 image1 referer1 page1 image1 120 85
page2 image2 referer2 page2 image2 200 400
page1 image1 referer1 page1 image1 750 1024
page2 image2 referer2 page2 image2 450 575
page1 image1 referer1 page1 image1 600 900
预期输出:
tab1.col1 | tab1.col2 | tab1.col3 | tab2.col3 | tab2.col4
==================================================================
page1 image1 referer1 600 900
page2 image2 referer2 200 400
这里是最后一组 returns 唯一行,但所有 tab1 列都在重复,这是我不想要的,在这种情况下,记录仅在 tab2.col1 和 tab2.col2 上有所不同。现在的要求是我希望 tab1.col1、tab1.col2、tab1.col3 是唯一的,并且对于来自 tab2 的那些列,只有一对相应的 tab2.col1 和 tab2.col2。 现在我无法从第二组删除 tab2.col1、tab2.col2 并应用最小或最大聚合函数,因为在那种情况下我不会获得映射到 tab2.col2 值的 tab2.col1 值对于特定记录。
注意:我使用 Amazon Redshift 作为数据库。子查询很重要,因为它实际上是从 3 table 连接生成的复杂结果集,如果我将这 3 table 的连接直接与 tab2 结合使用,那么查询将永远运行。为了这个问题的简单起见,假设子查询 returns col1, col2, col3 来自 table1。 Tab2 和 tab1 是巨大的 tables :D... 子查询显着提高了性能(将 20 分钟减少到 ~2 分钟)。
如果以下结果是您的要求,
tab1.col1 | tab1.col2 | tab1.col3 | tab2.col3 | tab2.col4
==================================================================
page1 image1 referer1 120 85
page2 image2 referer2 200 400
然后你可以使用下面的 redshift sql 查询来实现它
SELECT tab1.col1, tab1.col2, tab1.col3, tab2.col3, tab2.col4
FROM
(SELECT col1, col2, col3
FROM table1
GROUP BY col1, col2, col3) AS tab1
JOIN
(SELECT col1, col2, col3, col4
FROM
(SELECT col1, col2, col3, col4, ROW_NUMBER() OVER(PARTITION BY col1, col2 ORDER BY col3 ASC, col4 ASC) row_num
FROM table2) tab2
WHERE row_num = 1) tab2 ON tab1.col1 = tab2.col1
AND tab1.col2 = tab2.col2
上面sql语句中的关键是"ROW_NUMBER() OVER(PARTITION BY col1, col2 ORDER BY col3 ASC, col4 ASC)"。这将为您提供 tab2.col3 的 min 值和 tab2.col4 的 min 值。如果需要max值,则将顺序改为DESC
希望这能解决您的问题。
你也可以查看我写的结果集here