Получить последнюю запись дня для пользователя в SQL

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

Например:

Id      UserName               CreatedOn
1       B               2018-11-20
2       A               2018-12-20
3       A               2018-11-19
4       B               2018-11-18

Я хочу результат для пользователя A, B

Id      UserName               CreatedOn
2       A               2018-12-20
1       B               2018-11-20
0
Требуется больше образцов данных; ваш текущий результат может быть получен из ваших данных, просто используя select * из таблицы, где username = 'A'
добавлено автор Lee Mac, источник
Почему ID 4 не возвращается? Поскольку у вас нет значения времени, что определяет, что строка является «более поздней», ID имеет более высокое значение? (Учитывая, что значение ID становится больше по мере продвижения назад, это будет означать , что чем меньше число, тем новее.)
добавлено автор Larnu, источник
Ваше последнее изменение только запутывает вещи больше. Вы заявляете «Как получить последнюю запись в день пользователя, если в таблице несколько записей пользователей одного и того же пользователя в день» . Таким образом, на основе ваших данных должна быть возвращена каждая строка в ваших данных образца. Все они являются «самой последней» строкой за этот день, поскольку ни один пользователь не имеет несколько записей в тот же день .
добавлено автор Larnu, источник
@Larnu, я понял, что теперь, независимо от количества дней, он просто хочет получить последнюю запись дня/дней.
добавлено автор affanBajwa, источник
я ищу пользователя A прямо сейчас
добавлено автор Shailendra Pal, источник
Кто-нибудь может проверить мои требования к обновлению?
добавлено автор Shailendra Pal, источник

7 ответы

Create Table #tbl
(
Id Int,
UserName VarChar(25),
CreatedOn Date
)

Insert Into #tbl Values
(1,'B','2018-11-20'),
(2,'A','2018-12-20'),
(3,'A','2018-11-19'),
(4,'B','2018-11-18')


Select Username, Max(CreatedOn) As LastDT from #tbl
Group By UserName

Результат:

Username    LastDT
A           2018-12-20
B           2018-11-20

ОБНОВЛЕНИЕ: Это будет работать, если группировка по дням: использование выбора года с [DateTime]

Create Table #tbl
(
Id Int,
UserName VarChar(25),
CreatedOn DateTime
)

Insert Into #tbl Values
(1,'B','2018-11-20 10:45:12.000'),
(2,'A','2018-12-20 07:45:12.000'),
(3,'A','2018-11-19 09:45:12.000'),
(4,'B','2018-11-18 11:45:12.000'),
(5,'B','2018-11-20 01:50:12.000')

 Select  Username, Max(CreatedOn) As LastDT from #tbl
Where DatePart(year,CreatedOn) = '2018'
Group By UserName, DatePart(dayofyear ,CreatedOn)
Order By UserName

Результат по дням:

Username    LastDT
A           2018-11-19 09:45:12.000
A           2018-12-20 07:45:12.000
B           2018-11-18 11:45:12.000
B           2018-11-20 10:45:12.000
2
добавлено
Я верю, что это даст самую свежую запись всех времен, а ему нужна самая последняя запись каждого дня.
добавлено автор affanBajwa, источник
@affanBajwa, я обновил, чтобы позволить группировать по дням. Образцы данных не допускали этого, поэтому я предоставил поле DateTime для демонстрации.
добавлено автор level3looper, источник

Я полагаю, вы просто хотите получить последнюю запись для каждого пользователя

select  *
from    (
            select  *, rn = row_number() over (partition by UserName order by CreatedOn desc)
            from    yourtable
        ) d
where   d.rn = 1
order by CreatedOn desc
0
добавлено

Вы можете использовать dens_rank как в следующем выражении SQL

  select Id, UserName, CreatedOn
    from
    (
    select *,
           dense_rank() over ( partition by username order by CreatedOn desc) as
           max_CreatedOn 
      from t 
    ) q
   where max_CreatedOn = 1;

Rextester Demo

0
добавлено

Используя функцию WITH TIES на сервере SQL

SELECT TOP 2 WITH TIES UserName,CreatedOn  
FROM #tbl
ORDER BY ( ROW_NUMBER()OVER(PARTITION BY UserName ORDER BY CreatedOn DESC ))

Результат

UserName    CreatedOn
-----------------------
  A         2018-12-20
  B         2018-11-20
0
добавлено

Если вы хотите, чтобы результат только A записей означал, запрос ниже

SELECT * FROM myTable WHERE UserName = 'A' ORDER BY CreatedOn DESC

Если вы хотите, чтобы определенное количество строк A означало,

SELECT top 2 * FROM myTable WHERE UserName = 'A' ORDER BY CreatedOn DESC
0
добавлено

Если вам нужна последняя запись для каждого пользователя, то она должна работать:

SELECT UserName, MAX(CreatedOn) FROM yourTable GROUP BY UserName

Он вернет последнюю запись для каждого пользователя

Выход :

UserName       CreatedOn
    A          2018-12-20
    B          2018-11-20
0
добавлено
Но ОП ожидает 2 строки, а не 1.
добавлено автор Larnu, источник
Отредактировано после разъяснений ОП.
добавлено автор Noob dev, источник

Вы можете попробовать следующий простой запрос, используя ключевое слово TOP

Create Table #temp
(
Id Int,
UserName VarChar(25),
CreatedOn Date
)

Insert Into #temp Values
(1,'B','2018-11-20'),
(2,'A','2018-12-20'),
(3,'A','2018-11-19'),
(4,'B','2018-11-18')

Select TOP 2 * from #temp ORDER BY CreatedOn DESC

Вывод как показано ниже

Id  UserName    CreatedOn
-------------------------
2   A          2018-12-20
1   B          2018-11-20
0
добавлено
SqlCom.ru - Стиль жизни SQL
SqlCom.ru - Стиль жизни SQL
908 участник(ов)

Правила чата - https://t.me/sqlcom/88269 @sqlcom - основной канал (только MS SQL) @sql_ninja - второй канал (SQL вопросы начального уровня и свободное общение) @Gopnegbot - Викторина по SQL Server (наберите в привате /quiz). Предложения в @sql_ninja

SQL_Ninja
SQL_Ninja
340 участник(ов)

Правила чата - https://t.me/sqlcom/88269 @sqlcom - основной канал (только SQL) @sql_ninja - второй канал (SQL вопросы начального уровня и свободное общение) @Gopnegbot - Викторина по SQL Server (наберите в привате /quiz)