SQL Server - Как иметь неагрегированные столбцы в операторе Select при использовании группировки по? - PullRequest
0 голосов
/ 28 июня 2018

Я хочу MAX(Date) для каждого отдельного идентификатора. Это легко:

SELECT
    Id,
    MAX(LastModifiedDate)
FROM 
    [MyServer].[Database].[Table]
GROUP BY
    Id;

но мне также нужно включить другие столбцы, такие как имя, фамилия, компания и т. Д. который не может быть агрегирован, и он не будет работать, если я добавлю их в предложение GROUP BY, потому что тогда он возвращает строки, которые мне не нужны.

Ответы [ 5 ]

0 голосов
/ 28 июня 2018

Вы можете использовать subquery:

select t.*
from table t
where LastModifiedDate = (select max(t1.LastModifiedDate) 
                          from table t1 
                          where t1.id = t.id
                         );
0 голосов
/ 28 июня 2018

Понял это буквально, как только я опубликовал это. Я просто запутался в правильном способе использования оконной функции.

SELECT [Id]
  ,LastModifiedDate
  ,Row_Number() over (Partition by Id order by LastModifiedDate DESC) as rn
  ,[FirstName]
  ,[LastName]
  ,[Company]
  ,[Title]     
FROM [MyServer].[Database].[Table] as C
where rn = 1

То, что я пытался сделать, было:

,Row_Number() over (Partition by Id order by MAX(LastModifiedDate) DESC) as rn

но MAX не имеет смысла, потому что это DESC

0 голосов
/ 28 июня 2018

Используйте этот запрос для фильтрации по той же таблице по идентификатору и дате последнего изменения.

SELECT
    T.*
FROM
    [MyServer].[Database].[Table] AS T
    INNER JOIN (
        select Id,
        MAX(LastModifiedDate) AS  MaxLastModifiedDate
        FROM [MyServer].[Database].[Table]
        group by Id
    ) AS N ON 
        T.Id = N.Id AND
        N.MaxLastModifiedDate = T.LastModifiedDate

РЕДАКТИРОВАТЬ : Если у вас есть несколько максимальных дат для каждого идентификатора, вы не можете использовать их значение для фильтрации. Вместо них вы можете использовать ROW_NUMBER для ранжирования:

;WITH MaxByRowNumber AS
(
    SELECT
        T.*,
        LastModifiedDateRanking = ROW_NUMBER() OVER (PARTITION BY T.ID ORDER BY T.LastModifiedDate DESC)
    FROM 
        [MyServer].[Database].[Table] AS T
)
SELECT
    M.*
FROM
    MaxByRowNumber AS M
WHERE
    M.LastModifiedDateRanking = 1

Возможно, вы захотите добавить еще один столбец к ORDER BY, чтобы отвязать самые последние обновленные даты, или нет, в зависимости от ваших потребностей.

0 голосов
/ 28 июня 2018

Одним из способов будет использование CTE :

with cte as 
(
  select Id,
  max(LastModifiedDate) LastModifiedDate
  FROM [MyServer].[Database].[Table]
  group by Id
)
select t.*, c.LastModifiedDate
from [MyServer].[Database].[Table] t join cte c on t1.id = cte.id
0 голосов
/ 28 июня 2018

Чтобы сделать это, вместо использования group by, попробуйте over ():

select Id, <any other thing you want>,max(LastModifiedDate) over (partition by Id) as LastModifiedDate
FROM [MyServer].[Database].[Table]; 
...