SQL: выберите один элемент для имени с несколькими критериями - PullRequest
0 голосов
/ 20 марта 2019

Я пытаюсь выбрать один элемент для каждого значения в столбце «Имя» в соответствии с несколькими критериями.

Критерии, которые я хочу использовать, выглядят так:

  1. Включать только результаты, где IsEnabled = 1
  2. Вернуть единственный результат с наименьшим приоритетом (мы используем 1 для обозначения «высшего приоритета»)
  3. В случае ничьей верните результат с новейшей отметкой времени

Я видел несколько других вопросов, которые задают о возврате новейшей временной метки для заданного значения, и я смог адаптировать ее для возврата минимального значения Приоритета - но я не могу понять, как отфильтровать с приоритетом и отметкой времени.

Вот вопрос, который больше всего помог мне в этом.

Пример данных:

+------+------------+-----------+----------+
| Name |  Timestamp | IsEnabled | Priority |
+------+------------+-----------+----------+
|  A   | 2018-01-01 |     1     |    1     |
|  A   | 2018-03-01 |     1     |    5     |
|  B   | 2018-01-01 |     1     |    1     |
|  B   | 2018-03-01 |     0     |    1     |
|  C   | 2018-01-01 |     1     |    1     |
|  C   | 2018-03-01 |     1     |    1     |
|  C   | 2018-05-01 |     0     |    1     |
|  C   | 2018-06-01 |     1     |    5     |
+------+------------+-----------+----------+

Желаемый вывод:

+------+------------+-----------+----------+
| Name |  Timestamp | IsEnabled | Priority |
+------+------------+-----------+----------+
|  A   | 2018-01-01 |     1     |    1     |
|  B   | 2018-01-01 |     1     |    1     |
|  C   | 2018-03-01 |     1     |    1     |
+------+------------+-----------+----------+

То, что я пробовал до сих пор (это дает мне только включенные элементы с самым низким приоритетом, но не фильтрует для самого нового элемента в случае связи):

SELECT DATA.Name, DATA.Timestamp, DATA.IsEnabled, DATA.Priority
From MyData AS DATA
INNER JOIN (
  SELECT MIN(Priority) Priority, Name
  FROM MyData
  GROUP BY Name
) AS Temp ON DATA.Name = Temp.Name AND DATA.Priority = TEMP.Priority
WHERE IsEnabled=1

Вот и SQL-скрипка.

Как улучшить этот запрос, чтобы он возвращал только самый новый результат в дополнение к существующим фильтрам?

Ответы [ 2 ]

0 голосов
/ 20 марта 2019

Наиболее эффективный способ, который я нашел для этих проблем, - это использование CTE и ROW_NUMBER()

WITH CTE AS(
  SELECT *, ROW_NUMBER() OVER( PARTITION BY Name ORDER BY Priority, TimeStamp DESC) rn
  FROM MyData
  WHERE IsEnabled = 1
  )
SELECT Name, Timestamp, IsEnabled, Priority
From CTE
WHERE rn = 1;
0 голосов
/ 20 марта 2019

Использование row_number():

select d.*
from (select d.*,
             row_number() over (partition by name order by priority, timestamp) as seqnum
      from mydata d
      where isenabled = 1
     ) d
where seqnum = 1;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...