SQL выбирает самую последнюю запись для каждой группы

#sql #datetime #greatest-n-per-group

#sql #datetime #наибольшее-n-на-группу

Вопрос:

Я пытаюсь получить самую последнюю запись для каждого пользователя в моей таблице:

 SELECT *  
FROM Orders 
WHERE State = Active 
GROUP BY UserId
ORDER BY Orders.DateTimePlanned DESC`
  

Но это приводит меня к самой старой записи каждого пользователя, как я могу получить самую последнюю !? Изменение DESC на ASC не работает!

Пожалуйста, дайте мне знать!

Комментарии:

1. отметьте имя вашей СУБД и, если функция окна поддержки, попробуйте использовать row_number()

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

Ответ №1:

Ваш код не является допустимым стандартным SQL. Предположительно, вы используете MySQL с ONLY_FULL_GROUP_BY отключенным режимом sql.

Вам нужно фильтровать набор данных, а не агрегировать его. Один из вариантов использует подзапрос:

 select *  
from orders o
where state = 'Active' and datetimeplanned = (
    select max(o1.datetimeplanned)
    from orders o1
    where o1.userid = o.userid and o1.state = 'Active'
)
  

Вы также можете использовать оконные функции (доступные только в MySQL 8.0):

 select *  
from (
    select o.*, rank() over(partition by userid order by datetimeplanned desc) rn
    from orders o
    where state = 'Active'
) o
where rn = 1
  

Ответ №2:

Я бы использовал вложенный запрос

Взгляните на этот скрипт, он использует подзапрос, берет последнюю строку и уменьшает ее, используя значение предыдущей строки, чтобы спроецировать рост данных базы данных

объявить @backupType char(1) , @DatabaseName имя_системы

 set @DatabaseName   = db_name() --> Name of current database, null for all databaseson server
set @backupType     ='D'        /* valid options are:
                                D = Database 
                                I = Database Differential 
                                L = Log 
                                F = File or Filegroup 
                                G = File Differential 
                                P = Partial 
                                Q = Partial Differential
                                */



select  backup_start_date
      , backup_finish_date
      , DurationSec
      , database_name,backup_size
      , PreviouseBackupSize
      , backup_size-PreviouseBackupSize as growth
      ,KbSec= format(KbSec,'N2')
FROM (
select backup_start_date 
     , backup_finish_date
     , datediff(second,backup_start_date,b.backup_finish_date) as DurationSec 
     , b.database_name
     , b.backup_size/1024./1024. as backup_size

     ,case when datediff(second,backup_start_date,b.backup_finish_date) >0 
        then ( b.backup_size/1024.)/datediff(second,backup_start_date,b.backup_finish_date)
        else 0 end as KbSec
--   , b.compressed_backup_size
     , (      
        select top (1) p.backup_size/1024./1024. 
          from msdb.dbo.backupset p 
         where p.database_name = b.database_name
           and p.database_backup_lsn< b.database_backup_lsn
            and type=@backupType
         order by p.database_backup_lsn desc
        ) as PreviouseBackupSize
from msdb.dbo.backupset as b
where @DatabaseName IS NULL OR database_name =@DatabaseName
and type=@backupType
)as A
order by backup_start_date desc