SQL с использованием Rank и Row_Number с Order by - PullRequest
0 голосов
/ 09 сентября 2018

Я использую 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 

Я бы хотел получить самую последнюю Dx на основе DxDate. Row_number сработает, однако, если есть связь, подобная приведенной выше (01.10.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 (Случай, когда rank1 = rank1, затем CreateDate else DxDate End) DESC

Конечно, это не работает, потому что мне нужна какая-то итерация и я не могу поместить ее в подзапрос. Я также не могу использовать какие-либо производные таблицы для решения этой проблемы. Это возможно? Очень признателен!

Ответы [ 3 ]

0 голосов
/ 09 сентября 2018

Вы можете использовать только ROW_NUMBER () и ORDER BY CreateDate, это будет работать.

ROW_NUMBER () OVER (PARTITION ПО DOCID ЗАКАЗАТЬ CreateDate DESC) AS rownum1

0 голосов
/ 09 сентября 2018

В соответствии с вашими примерами данных просто нужно под запросом

  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
0 голосов
/ 09 сентября 2018

Вы должны иметь возможность использовать 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, чтобы решить, какая из них действительно "первая". . "

Демо

Примечание: в вашей демонстрации две записи имеют разные DocID значения, но я думаю, что вы предполагали, чтобы они имели одинаковое значение. В приведенной выше демонстрационной ссылке я изменил две записи, чтобы они имели одинаковое значение DocID, и логика работает.

...