SQL 使用 Rank 和 Row_Number 使用 Order by
SQL using Rank and Row_Number with Order by
我正在使用 SSMS 2018 并有一个 table 类似于此:
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
获取最新的 Dx
。 Row_number
会起作用,但是,如果有像上面那样的领带 (10/1/2015),我希望最近的领带基于 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
当然这行不通,因为我需要某种迭代并且不能将它放在子查询中。
我也不能使用任何派生的 tables 来解决这个问题。这可能吗?
非常感激!
您应该能够将 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;
上述查询与您的想法相比唯一的主要变化是 DocID
和 DxDate
值相同的两条记录随后将由 CreateDate
进行比较决定哪一个才是真正的 "first."
注意:在您的演示中,两条记录具有 不同的 DocID
值,但我认为您希望它们具有相同的值。在上面的演示 link 中,我将两条记录更改为具有相同的 DocID
值,逻辑正常。
您只能使用 ROW_NUMBER() 和 ORDER BY CreateDate 它会起作用。
ROW_NUMBER() OVER (PARTITION BY DocID ORDER BY CreateDate DESC) AS rownum1
根据你的样本数据只需要下面查询
SELECT top 1 *
FROM DxList
order by DxDate desc,CreateDate desc
但是根据你的描述按照@Tim提供的查询
在此 link 两个查询中,您都会找到
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
我正在使用 SSMS 2018 并有一个 table 类似于此:
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
获取最新的 Dx
。 Row_number
会起作用,但是,如果有像上面那样的领带 (10/1/2015),我希望最近的领带基于 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
当然这行不通,因为我需要某种迭代并且不能将它放在子查询中。 我也不能使用任何派生的 tables 来解决这个问题。这可能吗? 非常感激!
您应该能够将 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;
上述查询与您的想法相比唯一的主要变化是 DocID
和 DxDate
值相同的两条记录随后将由 CreateDate
进行比较决定哪一个才是真正的 "first."
注意:在您的演示中,两条记录具有 不同的 DocID
值,但我认为您希望它们具有相同的值。在上面的演示 link 中,我将两条记录更改为具有相同的 DocID
值,逻辑正常。
您只能使用 ROW_NUMBER() 和 ORDER BY CreateDate 它会起作用。
ROW_NUMBER() OVER (PARTITION BY DocID ORDER BY CreateDate DESC) AS rownum1
根据你的样本数据只需要下面查询
SELECT top 1 *
FROM DxList
order by DxDate desc,CreateDate desc
但是根据你的描述按照@Tim提供的查询
在此 link 两个查询中,您都会找到
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