Как получить строку SQL по максимуму одного столбца, сгруппировать по другому столбцу - PullRequest
5 голосов
/ 19 января 2012

Мне нужно считать пользователей из старой базы данных, чтобы использовать их для статистики в новой системе, но у меня нет исходной таблицы пользователей. Однако есть таблица статистики с суммой каждого года, где я также могу найти всю необходимую информацию о пользователях. Кроме того, это также дает мне только пользователей, которые были активными, и это то, что мне нужно.

Таблица имеет следующие соответствующие столбцы: (столбцы статистики здесь не релевантны)

  • Идентификатор_пользователь
  • 1008 * FirstName *
  • LastName
  • E-mail
  • год

Я хочу, чтобы идентификатор пользователя отличался, поэтому это единственный столбец, который я могу иметь в GROUP BY. Я буду запускать MAX на Year, чтобы получить значения за последний год. FirstName, LastName и Email должны совпадать со строкой, где MAX (год). Другими словами, люди могли менять имена и адреса электронной почты в течение многих лет, и я хочу только последнее, так как оно имеет отношение только к делу.

Мое лучшее предложение для запроса SQL выглядит так:

SELECT UserID, Firstname, LastName, Email, MAX(Year) AS Year
FROM myTable
GROUP BY UserID
ORDER BY LastName, FirstName

Единственная проблема заключается в том, что SQL Server 2008 не позволяет мне делать что-либо подобное, потому что все столбцы должны быть с функцией, подобной MAX, или частью GROUP BY. Столбцы FirstName, LastName и Email не могут быть в GROUP BY, потому что это приведет к слишком большому количеству записей. Кажется, что-то работает, чтобы поставить MAX на всех из них, но тогда у меня нет возможности узнать, над каким столбцом в действительности работает функция MAX. Я не знаю наверняка, что это будет проблемой, но у меня нет времени, чтобы просмотреть 100 000 строк, чтобы увидеть, есть ли на самом деле проблема.

Короче говоря, я хочу целую строку из пяти столбцов, где MAX работает только для одного столбца, а GROUP BY - для другого. У кого-нибудь есть хорошее решение или действительно безопасно использовать MAX для всех не группирующих строк?

Ответы [ 2 ]

14 голосов
/ 19 января 2012

Несколько ответов ...


Коррелированный подзапрос ...

SELECT
  *
FROM
  myTable
WHERE
  Year = (SELECT MAX(Year) FROM myTable AS lookup WHERE lookup.UserID = myTable.UserID)


Присоединяйтесь к производному агрегату

SELECT
  *
FROM
  myTable
INNER JOIN
  (SELECT UserID, MAX(Year) AS Year FROM myTable GROUP BY UserID) AS lookup
    ON  lookup.UserID = myTable.UserID
    AND lookup.Year   = myTable.Year


Заказано CTE с использованием ROW_NUMBER () ...

WITH
  sequenced_data AS
(
  SELECT
    ROW_NUMBER() OVER (PARTITION BY UserID ORDER BY Year DESC) AS sequence_id,
    *
  FROM
    myTable
)
SELECT
  *
FROM
  sequenced_data
WHERE
  sequence_id = 1
3 голосов
/ 19 января 2012

у вас есть только один год записи на пользователя?Если да, то вы можете использовать old'n'good join:

SELECT m.UserID, m.Firstname, m.LastName, m.Email, m.Year
FROM myTable m
    INNER JOIN (
        SELECT UserID, MAX(Year) as Year
        FROM myTable
        GROUP BY UserID
    ) x ON x.UserID=m.UserID and x.Year=m.Year
ORDER BY m.LastName, m.FirstName

Конечно, вы можете использовать конструкции из более новых версий SQL, я просто привык к более старым (= более общим) возможностям:).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...