SQL Выбрать регистр, когда количество> 1 - PullRequest
1 голос
/ 17 июня 2020

У меня есть таблица, которая выглядит как показано ниже.

ParentID | PersonID | Year 
----------------------------  
1             1       2019
1             2       2020
3             3       2019
3             4       2020
5             5       2019

Я пытаюсь понять, как выбрать текущий PersonID, когда ParentID имеет более одной записи, чтобы мои результаты выглядели так, как показано ниже.

ParentID | PersonID | Year 
----------------------------  
1             2       2020
3             4       2020
5             5       2019

Я могу Не выбирайте только максимальный PersonID, потому что мы иногда создаем записи Person за предыдущий год, и в этом случае PersonID больше, и мы все равно хотим вернуть запись этого года. Я также не могу выбирать по году, потому что, если у них нет рекорда за этот год, нам все равно понадобится их самый последний рекорд за каждый год, который есть.

Я пробовал выбрать это подмножество полдюжиной способов на этом этапе, и мне удалось только повредить мозг. Любая помощь будет оценена !!

Ответы [ 2 ]

1 голос
/ 17 июня 2020

Это типичная проблема с наибольшим числом n на группу. Чтобы решить эту проблему, вам нужно подумать о фильтрации , а не агрегации .

Переносимое решение - фильтровать с помощью коррелированного подзапроса, который возвращает последние year на parent_id:

select t.*
from mytable t
where t.year = (
    select max(t1.year) from mytable t1 where t1.parent_id = t.parent_id
)
0 голосов
/ 17 июня 2020

Предполагая, что вы используете MS SQL, это может быть достигнуто с помощью ROW_NUMBER. Подробнее про ROW_NUMBER можно прочитать здесь . PARTITION BY делит результат на разделы и применяет номера строк к разделам. Итак, применив разделение к ParentId и отсортировав по Year по убыванию, данные отсортированы ParentId по Year. Затем удалите старые данные, используя условие RowNo = 1.

Create Table Test(ParentId int, PersonId int, Year int);
INSERT INTO Test values 
(1, 1, 2019), 
(1, 2, 2020),
(3, 3, 2019),
(3, 4, 2020), 
(5, 5, 2019);

SELECT ParentId, PersonId, Year FROM
(
  SELECT ROW_NUMBER() OVER(PARTITION BY ParentId 
  ORDER BY Year /* Use PersonId if it fits correctly */ DESC) AS RowNo,
  ParentId, PersonId, Year from Test -- Table Name
 ) E WHERE ROWNo = 1
...