如何在不对结果集中的其余列应用聚合函数的情况下,基于多个唯一列选择数据

时间:2016-11-02 18:23:33

标签: mysql amazon-redshift distributed query-performance distinct-values

这可能看似重复,但我找不到符合我要求的答案。提到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

这里最后一组返回唯一的行,但所有tab1 cols都是重复的,我不想要,在这种情况下,记录仅在tab2.col1和tab2.col2上有所不同。现在的要求是我希望tab1.col1,tab1.col2,tab1.col3是唯一的,并且只需要tab2中的那些列的一对相应的tab2.col1和tab2.col2。 现在我无法从第二组中删除tab2.col1,tab2.col2并应用最小或最大聚合函数,因为在这种情况下我不会得到tab2.col1值,该值映射到tab2.col2值特别记录。

注意:我使用Amazon Redshift作为数据库。子查询很重要,因为它实际上是一个由3个表连接产生的复杂结果集,如果我直接使用tab2连接这3个表,那么查询将永远运行。为了简化这个问题,我们假设子查询从table1返回col1,col2,col3。 Tab2和tab1是巨大的表格:D ...子查询大大提高了性能(减少了20分钟到2分钟)。

1 个答案:

答案 0 :(得分:0)

如果您的要求低于以下结果,

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 最小值tab2.col4 。如果您需要最大值,请将订单更改为 DESC

希望这可以解决你的问题。

您还可以查看我编写的结果集here