【问题标题】:sql select last but one record from every groupsql从每个组中选择最后一条记录
【发布时间】:2018-04-11 16:28:02
【问题描述】:

请帮助我建立以下查询: 我有一个来自选择查询的连接表:

select nevlista.nevID as ColA, nkhk.nevktghID as ColB, nkhk.ktghelyID as ColC 
from nevlista
inner join nkhk on nevlista.nevID = nkhk.nevID
where nevlista.nevID = nkhk.nevID

这给出了以下结果:

 ColA   ColB ColC
 90002  629 6
 90003  835 9
 90003  875 12
 90003  112 12
 90004  424 17
 90004  570 1
 90004  905 17
 90005  648 1
 90005  649 17
 90005  523 17
 and so on...

现在,我需要 ColA 中每一组相同的 ID,最后一个但最高的值来自 ColB(以及来自 ColC 的值)。 (ColA中相同ID的数量不同,通常有2到5条相同ID的记录)。

【问题讨论】:

  • 您能否为您的演示数据添加正确的结果集?我认为这将有助于了解您想要什么。
  • 正确的结果集是:90003 - 835, 90004 - 570, 90005 - 648, ... Zohar Peled 的答案对我有用“其中 rn = 2”。但我认为你的解决方案也可以,我稍后会测试它。谢谢大家的帮助!

标签: sql sql-server


【解决方案1】:

最简单的做法是使用Row_number 的cte,按colA 分区,按colB desc 排序:

;With cte as
(
    select  nevlista.nevID as ColA, 
            nkhk.nevktghID as ColB, 
            nkhk.ktghelyID as ColC,
            ROW_NUMBER() OVER(PARTITION BY nevlista.nevID ORDER BY nkhk.nevktghID DESC) as rn
    from nevlista
    inner join nkhk on nevlista.nevID = nkhk.nevID
    where nevlista.nevID = nkhk.nevID
)

select ColA, ColB, ColC
FROM CTE
WHERE rn = 2 -- assiming every nevlista.nevID appears at least twice in the cte

【讨论】:

  • 在 rn = 2 的情况下,它给了我每组 ColB 的最后一个但最高的值,所以这可能就是它!谢谢!
  • 如果你的 nevID 值只存在于一行中怎么办?
  • 这不会出现在查询结果中,但幸运的是在我的数据环境中这不是问题。 (现在……)
【解决方案2】:

您可以将排名函数row_number()ties 方法一起使用

select top(1) with ties nl.nevID as cola, n.nevktghID as colb, n.ktghelyID as colc
from nevlista nl 
inner join nkhk n on nl.nevID = n.nevID
order by row_number() over (partition by nl.nevID order by n.nevktghID  desc)

而且,我怀疑在joins 之后不需要使用where 子句

【讨论】:

  • 好主意!我从未尝试在ORDER BY 块中使用ROW_NUMBER
  • 我一直忘记with ties... where 子句也很好。 +1
  • 这也给出了 ColB 的最高值。我需要最后一个但最高的,但我不知道如何更改此查询来获得它。
  • @ajudi 最后一个?如果不是最高值,您如何识别最后一个?关系中没有隐含的顺序...
  • 对不起,如果我误解了你,我的英语不是最好的。是的,最后一个是最高的,但我不需要最高,我需要最高之前的那个,例如,对于 ColA 中的 90003,在 ColB 中将是 835。所以我想需要的一个步骤是在每个组中以正确的顺序获取 ColB(这是隐式顺序吗?),然后选择每个组的第二条记录。
【解决方案3】:

考虑将group bymax 一起使用:

select nevlista.nevID as ColA, nkhk.nevktghID as ColB, nkhk.ktghelyID as ColC 
from nevlista
join nkhk on nevlista.nevID = nkhk.nevID
join
(
    select nevID, max(nevktghID) max_nevktghID
    from nkhk 
    group by nevID
) t1 on nkhk.nevID = t1.nevID and
        nkhk.nevktghID = t1.max_nevktghID

如果您有以下索引,则可以是considerably faster on SQL Server

CREATE NONCLUSTERED INDEX ix_nkhk _nevID_nevktghID
  ON nkhk (nevID,nevktghID) INCLUDE (ktghelyID)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-05
    • 1970-01-01
    • 1970-01-01
    • 2021-01-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多