SQL-запрос для возврата только 1 записи на идентификатор группы - PullRequest
20 голосов
/ 23 декабря 2009

Я ищу способ справиться со следующим сценарием. У меня есть таблица базы данных, в которой мне нужно возвращать только одну запись для каждого «идентификатора группы», содержащегося в таблице, кроме того, запись, выбранная в каждой группе, должна быть самой старой в семье.

ID   Group ID   Name               Age
1   134        John Bowers        37
2   134        Kerri Bowers       33
3   135        John Bowers        44
4   135        Shannon Bowers     42

Таким образом, в приведенных выше примерах данных мне понадобятся идентификаторы 1 и 3, поскольку они являются самыми старыми людьми в каждой группе.

Это запрашивается к базе данных SQL Server 2005.

Ответы [ 4 ]

30 голосов
/ 23 декабря 2009
SELECT  t.*
FROM    (
        SELECT  DISTINCT groupid
        FROM    mytable
        ) mo
CROSS APPLY
        (
        SELECT  TOP 1 *
        FROM    mytable mi
        WHERE   mi.groupid = mo.groupid
        ORDER BY
                age DESC
        ) t

или это:

SELECT  *
FROM    (
        SELECT  *, ROW_NUMBER() OVER (PARTITION BY groupid ORDER BY age DESC) rn
        FROM    mytable
        )
WHERE   rn = 1

Это вернет максимум одну запись на группу даже в случае связей.

См. Эту статью в моем блоге для сравнения производительности обоих методов:

4 голосов
/ 23 декабря 2009

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

SELECT DISTINCT
       t.groupid,
       t.name
  FROM TABLE t
  JOIN (SELECT t.groupid,
               MAX(t.age) 'max_age'
          FROM TABLE t
      GROUP BY t.groupid) x ON x.groupid = t.groupid
                           AND x.max_age = t.age

Так что, если в группе есть 2+ человека одного возраста? Лучше хранить дату рождения, чем возраст - вы всегда можете рассчитать дату рождения для презентации.

1 голос
/ 23 декабря 2009

Попробуйте это (если Группа является синонимом Домашнее хозяйство )

Select * From Table t
Where Age = (Select Max(Age)
             From Table 
             Where GroupId = t.GroupId)

Если в каком-либо домашнем хозяйстве есть два или более «старейших» человека (все они одного возраста и нет никого старше), это вернет их всех, а не одного случайного.

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

Select * From Table t
Where Id = 
  (Select Max(Id) Fom Table 
   Where GroupId = t.GroupId
      And Age =
         (Select(Max(Age) From Table
          Where GroupId = t.GroupId))
0 голосов
/ 23 декабря 2009
SELECT GroupID, Name, Age
FROM table
INNER JOIN
(
SELECT GroupID, MAX(Age) AS OLDEST
FROM table
) AS OLDESTPEOPLE
ON
table.GroupID = OLDESTPEOPLE.GroupID
AND
table.Age = OLDESTPEOPLE.OLDEST
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...