#sql #sql-server #tsql
#sql #sql-сервер #tsql
Вопрос:
Я использую ROW_NUMBER(), чтобы упорядочить количество раз, когда определенный код используется для каждого идентификатора посещения. Ниже приведена измененная часть запроса для примера.
SELECT
ROW_NUMBER() OVER (PARTITION BY VisitID ORDER BY EventActualDateTime) AS 'RowNum'
,VisitID
,EventActualDateTime
,Code
,LocationID
FROM
AdmVisitEvents
WHERE
VisitID = '6012227281'
and Code IN ('ENADMIN','TFRADMIN')
Я пытаюсь найти способ исключить СТРОКУ, если LocationID совпадает с предыдущей строкой.
Итак, мой результирующий набор должен выглядеть следующим образом:
Это могло произойти и ранее при подсчете строк. Например, если бы первый код TFRADMIN имел тот же LocationID, что и код ENADMIN *, мне нужно было бы также пропустить эту строку. (*Коды ‘ENADMIN’ или ‘OBSVTOIN’ всегда будут строкой 1, а СТРОКА 2 всегда будет кодом ‘TFRADMIN’).
Итак, другим примером может быть:
Если это был мой результат, он должен показывать только:
Комментарии:
1. Какую версию SQL-Сервера вы используете?
2. SQL Server 2016
Ответ №1:
Это непроверено из-за отсутствия пригодных для использования образцов данных (изображение не пригодно для использования, поскольку единственный способ, которым добровольцы могут его использовать, — это моя расшифровка), однако, LAG
должно помочь вам достичь этого:
WITH CTE AS
(SELECT VisitID,
EventActualDateTime,
Code,
LocationID,
LAG(LocationID) OVER (PARTITION BY VisitID ORDER BY EventActualDateTime) AS PreviousLocationID
FROM AdmVisitEvents
WHERE VisitID = '6012227281'
AND Code IN ('ENADMIN', 'TFRADMIN'))
SELECT ROW_NUMBER() OVER (PARTITION BY VisitID ORDER BY EventActualDateTime) AS RowNum,
VisitID,
EventActualDateTime,
Code,
LocationID
FROM CTE
WHERE LocationID != PreviousLocationID OR PreviousLocationID IS NULL;
Обратите внимание, что PARTITION BY
предложения на самом деле не нужны в этих запросах из-за вашего WHERE
( VisitID = '6012227281'
). Поскольку VisitID
может иметь только одно скалярное значение, PARTITION BY
никогда не будет генерироваться значений для другого «набора».
Комментарии:
1.
VisitID
Было указано только для примера, оно будет удалено в полном запросе. Итак, мне действительно нужноpartition by
в конечном счете, я просто забыл удалить его здесь.
Ответ №2:
Вы можете использовать предложение row_number()
with ties
:
SELECT TOP (1) WITH TIES VisitID, EventActualDateTime, Code, LocationID
FROM AdmVisitEvents
WHERE VisitID = '6012227281' AND
Code IN ('ENADMIN','TFRADMIN')
ORDER BY ROW_NUMBER() OVER (PARTITION BY VisitID, Code, LocationID ORDER BY EventActualDateTime);