0

我正在重建的查询中有以下片段:

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_ID,然后过滤为WHERE RANK1 = 1. 退回所有这些记录只是在之后立即丢弃它们似乎有点浪费

4

1 回答 1

2

您可以将查询重写为如下所示:

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().

于 2013-01-07T15:43:36.143 回答