选择最新的数据(内连接+分组可能)

m3d*_*iv0 5 sql-server-2008

我想我需要一些帮助。为了简化我的问题,假设我有两个表。首先使用这种结构称为“主题”:

idTopic  author  deleted
1        123     false
2        132     false
Run Code Online (Sandbox Code Playgroud)

第二个称为“文本”,如下所示:

idTopic idText datePosted
1       11     1
1       12     2
2       15     1
2       18     3
Run Code Online (Sandbox Code Playgroud)

我需要的是使用该主题的最新文本数据为每个主题选择数据。所以我的输出应该是这样的:

idTopic author deleted idText datePosted
1       123    false   12     2
2       132    false   18     3
Run Code Online (Sandbox Code Playgroud)

那么我的 sql 查询应该如何显示?我试图对由 idTopic 分组的第二个表进行一些内部连接,但没有奏效。

谢谢

孔夫子*_*孔夫子 5

select idTopic, author, deleted, idText, datePosted
from
(
    select t.idTopic, t.author, t.deleted, x.idText, x.datePosted,
           row_number() over (partition by t.idTopic order by x.datePosted desc) rn
    from topics t
    left join texts x on t.idTopic = x.idTopic -- or INNER JOIN
) z
where rn=1
Run Code Online (Sandbox Code Playgroud)
  1. 查看ROW_NUMBER()函数,该函数用于为每个“分区”中的每一行提供唯一的序列号。在这种情况下,partition by t.idTopic告诉函数对相同的每组记录进行独立编号t.idTopic

  2. 在每个分区内,记录根据特定顺序编号为 1,2,3...,在这种情况下是order by x.datePosted desc- 将最新帖子放在最前面。

  3. LEFT JOIN也全称为“LEFT OUTER JOIN”,用于将表的所有记录保留在左侧,即使右侧没有记录。如果您不需要查看没有文本的主题,只需删除“LEFT”关键字即可。

  4. 查询被移到派生表中并取别名(不重要的是 as z),以便我们可以对其进行过滤以查找 where rn = 1。回想一下,每个分区只能有一行的值 rn=1,根据我们的ORDER BY clausein定义,ROW_NUMBER()具有最新文本的行。


小智 5

最简单的方法是使用 CTE(通用表表达式),它使用 ROW_NUMBER 函数按发布日期对 idtopic 进行排名。就像是:

;WITH ranked AS
(
SELECT
    idTopic,
    idtext,
    datePosted,
    ROW_NUMBER() OVER (PARTITION BY idtopic ORDER BY datePosted DESC) AS rowNum
FROM
    dbo.texts
)
SELECT
    T.idTopic,
    T.author,
    T.deleted,
    R.idtext,
    R.datePosted
FROM
    ranked R
INNER JOIN dbo.topics T
    on R.idTopic = T.idTopic
WHERE
    rownum = 1
Run Code Online (Sandbox Code Playgroud)