【问题标题】:SQL using Rank and Row_Number with Order bySQL 使用 Rank 和 Row_Number 以及 Order by
【发布时间】:2019-02-13 21:53:23
【问题描述】:

我正在使用 SSMS 2018 并且有一个类似于此的表:

CREATE TABLE DxList (DocID INT, Dx VARCHAR(255), DxDate DATE, CreateDate DATETIME);

INSERT INTO DxList (DocID, Dx, DxDate, CreateDate)
VALUES (6018, 'OSDD', '10/01/2015', '10/09/2015 12:27');

INSERT INTO DxList (DocID, Dx, DxDate, CreateDate)
VALUES (6018, 'ADHD', '10/01/2015', '10/09/2015 18:14');

SELECT *
FROM DxList

DocID   Dx      DxDate      CreateDate       
6018    OSDD    10/1/2015   10/9/2015 12:27   
6018    ADHD    10/1/2015   10/9/2015 18:14 

我想根据DxDate 获取最新的DxRow_number 会起作用,但是,如果有像上面那样的平局(2015 年 10 月 1 日),我希望最近的平局基于 CreateDate

在这种情况下,我希望我的结果是:

DocID   Dx      DxDate      CreateDate        
6018    ADHD    10/1/2015   10/9/2015 18:14  

我相信我可以在此查询中使用Rank(),但我不确定如何使用。到目前为止,这是我的查询:

SELECT DISTINCT
  DocID,
  Dx,
  DxDate,
  CreateDate,
  rownum1,
  rank1
FROM (SELECT
  DocID,
  Dx,
  DxDate,
  CreateDate,
  RANK() OVER (PARTITION BY DocID ORDER BY DxDate DESC) AS rank1,
  ROW_NUMBER() OVER (PARTITION BY DocID ORDER BY DxDate DESC) AS rownum1
FROM DxList) b
WHERE rownum1 = 1

我相信我正在寻找类似的东西:

Order By (Case When rank1=rank1 then CreateDate else DxDate End) DESC

当然这不起作用,因为我需要某种迭代并且不能将其放入子查询中。 我也不能使用任何派生表来解决这个问题。这可能吗? 非常感激!

【问题讨论】:

  • 我认为您的示例输出是错误的,因为 DocID 不同,但根据您的描述,它会是相同的

标签: sql sql-server window-functions row-number


【解决方案1】:

您应该能够将ROW_NUMBER 与两层ORDER BY 子句一起使用:

SELECT DocID, Dx, DxDate, CreateDate
FROM
(
    SELECT *,
        ROW_NUMBER() OVER (PARTITION BY DocID ORDER BY DxDate DESC, CreateDate DESC) rn
    FROM DxList
) t
WHERE rn = 1;

上述查询与您的想法相比,唯一的主要变化是DocIDDxDate 值相同的两条记录随后将由CreateDate 进行比较,以确定哪个是真正的“第一个” 。”

Demo

注意:在您的演示中,两条记录具有不同 DocID 值,但我认为您希望它们具有相同的值。在上面的演示链接中,我已将两条记录更改为具有相同的DocID 值,并且逻辑正常。

【讨论】:

  • 我把它弄得多么复杂,我都惊叫了起来。你是对的——这会奏效。在我的真实数据中,它更复杂,DocID 实际上是不同的。但是,我将更改示例数据以使其更清晰,因为我按 DocID 进行了分区。非常感谢!
【解决方案2】:

您只能使用 ROW_NUMBER() 和 ORDER BY CreateDate 它会起作用。

ROW_NUMBER() OVER (PARTITION BY DocID ORDER BY CreateDate DESC) AS rownum1

【讨论】:

    【解决方案3】:

    根据您的示例数据只需要下面的查询

      SELECT top 1 *           
            FROM DxList
            order by DxDate desc,CreateDate desc
    

    但根据您的描述,请按照@Tim 提供的查询

    在此链接中,您将找到两个查询

    https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=44fdd4b2e849137cebe9df837ac41a39

    DocID   Dx  DxDate  CreateDate
    6018    ADHD    01/10/2015 00:00:00 09/10/2015 18:14:00
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-24
      • 2012-04-13
      • 2011-06-16
      • 2017-10-21
      • 2020-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多