理解PARTITION BY和是否有更好的方法得到相同的答案



我从我正在重新构建的查询中获得以下代码片段:

LEFT JOIN (SELECT ACCOUNT_ID, LETTER_TYPE, LETTER_DATE, LETTER_ID
           FROM (SELECT T1.ACCOUNT_ID, T2.LETTER_TYPE, T1.LETTER_DATE, T1.LETTER_ID,
                 DENSE_RANK() OVER (PARTITION BY T1.ACCOUNT_ID, T2.LETTER_TYPE
                                    ORDER BY T1.LETTER_DATE DESC) AS RANK1
                 FROM tableOne T1
                 INNER JOIN tableTwo T2 ON T1.LETTER_ID = T2.LETTERID)
           WHERE RANK1 = 1)

我之前没有真正处理过DENSE_RANK()PARTITION BY,但根据我的研究,这种情况会转化为"按ACCOUND_ID和LETTER_DATE降序排序这组记录),然后外部SELECT只抓取RANK = 1的记录。因此,它基本上是试图找到每个帐户最近发送的LETTER_ID。

我的问题是:A。这个翻译准确吗?和 B。是否有一种方法可以重写/重构此查询,使其不必像这样嵌套?

我在B中的意思。是它首先返回所有的LETTER_IDs,然后过滤到WHERE RANK1 = 1。返回所有这些记录,然后立即丢弃它们似乎有点浪费

您可以这样重写查询:

LEFT JOIN (select t1.account_id, t2.letter_type, MAX(t1.letter_date) as MaxDate
           from tableOne t1 join tableTwo t2 on T1.LETTER_ID = T2.LETTERID
          ) maxt left outer join
          (select T1.ACCOUNT_ID, T2.LETTER_TYPE, T1.LETTER_DATE, T1.LETTER_ID
           from tableOne t1 join tableTwo t2 on T1.LETTER_ID = T2.LETTERID
          ) t
          on t.account_id = tmax.account_id and t.letter_type = tmax.letter_type and
             t.letter_date = tmax.maxdate

然而,我建议你,窗口/分析函数是非常强大的SQL添加,所以你应该学习如何使用它们。

在这种情况下有一个问题。如果最近的letter_date上有多个字母,那么您的查询(以及这个查询)将返回所有字母。也许你的意图是只归还其中一个。在这种情况下,您可以使用row_number()而不是dense_rank()

相关内容

最新更新