Как я могу запросить одну запись, разделенную полем в SQL? - PullRequest
0 голосов
/ 27 апреля 2018

У меня есть таблица SQL Server, которая имеет данные в формате:

Timestamp     Name     Price
2018-01-02    Name1    0.10
2018-01-03    Name1    0.20
2018-01-04    Name1    0.30
2018-01-02    Name2    0.40
2018-01-03    Name2    0.50
2018-01-04    Name2    0.60
2018-01-02    Name3    0.70
2018-01-03    Name3    0.80
2018-01-05    Name3    0.90

И я пытаюсь написать запрос на выборку, который возвращает самый последний (Timestamp) для каждого уникального Name. Таким образом, для приведенного выше примера данных запрос должен вернуть:

Timestamp     Name     Price
2018-01-04    Name1    0.30
2018-01-04    Name2    0.60
2018-01-05    Name3    0.90

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

SELECT TOP 1 * FROM mytable ORDER BY Timestamp DESC GROUP BY Name

однако, здесь есть синтаксическая ошибка.

Кто-нибудь знает, возможен ли такой запрос? Как получить самые последние строки (Timestamp) для каждого уникального Name?

Я использую Microsoft Azure SQL, если это имеет значение.

Ответы [ 4 ]

0 голосов
/ 28 апреля 2018

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

select * 
from table t
where timestamp  = (select max(timestamp) from table where name = t.name);

Примечание: будьте осторожны, если у вас одинаковая дата с тем же именем

0 голосов
/ 27 апреля 2018

В Sql ORDER BY всегда идет после GROUP BY
Кроме того, SELECT * с GROUP BY не будет работать на большинстве баз данных.

Но в MS SQL Server вы можете комбинировать TOP с TIES и ORDER BY ROW_NUMBER.

SELECT TOP 1 WITH TIES *
FROM mytable
ORDER BY ROW_NUMBER() OVER (PARTITION BY Name ORDER BY Timestamp DESC)

Если результат также должен быть отсортирован по полям, используемым в РАЗДЕЛЕ, просто введите подзапрос.

SELECT *
FROM (
   SELECT TOP 1 WITH TIES *
   FROM mytable
   ORDER BY ROW_NUMBER() OVER (PARTITION BY Name ORDER BY Timestamp DESC)
) q
ORDER BY Name
0 голосов
/ 28 апреля 2018

Другим подходом будет использование CTE для поиска пар меток времени и имен, а затем присоединение к базовой таблице для проекции столбца цен:

WITH CandidateRows ([Timestamp],[Name])
AS
(
  Select MAX([Timestamp]), [Name] From TestTable GROUP BY [Name]
)
SELECT T1.[Timestamp], T1.[Name], T2.[Price] 
  FROM CandidateRows T1 JOIN TestTable T2 
  ON T1.[Timestamp] = T2.[Timestamp] AND T1.[Name] = T2.[Name]  
  ORDER BY T1.[Name] ASC
0 голосов
/ 27 апреля 2018

Попробуйте row_number():

select t.*
from (select t.*,
             row_number() over (partition by name order by timestamp desc) as seqnum
      from mytable t
     ) t
where seqnum = 1;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...