Как вернуть последнюю строку, написанную за день? - PullRequest
3 голосов
/ 10 февраля 2009

У меня есть таблица с FooId и столбцом CreatedTime. В течение дня несколько строк могут быть вставлены для одного и того же FooId. Столбец CreatedTime представляет время в момент вставки.

Я бы хотел запрос, который вернет мне самую последнюю строку для данного дня (например, 2000-01-01). Есть ли способ написать запрос, который будет делать это с SQL Server 2005?

Ниже приведен пример данных и ожидаемого результата. Я бы хотел, чтобы последние данные были созданы за день. Так что MAX (CreatedDate) не будет работать Спасибо!

FooId   Data  CreatedTime
---------------------------
1       A     2000/01/01 12:00:00
1       B     2000/01/01 12:12:00
1       C     2000/01/01 12:25:00
2       A     2000/01/01 12:00:00
2       B     2000/01/01 12:26:00
3       A     2000/01/01 12:00:00

Результат

FooId   Data  CreatedTime
---------------------------
1       C     2000/01/01 12:25:00
2       B     2000/01/01 12:26:00
3       A     2000/01/01 12:00:00

Ответы [ 9 ]

4 голосов
/ 10 февраля 2009

конечно, он будет работать с MAX

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

запустить это

    CREATE TABLE #MaxVal(id INT,VALUE varchar(10),SomeDate DATETIME)
    INSERT #MaxVal VALUES(1,'a','2009-02-10 14:48:45.143')
    INSERT #MaxVal VALUES(1,'b','2009-02-10 13:48:45.143')
    INSERT #MaxVal VALUES(1,'c','2009-02-10 11:48:45.143')
    INSERT #MaxVal VALUES(2,'d','2009-02-10 11:48:45.143')
    INSERT #MaxVal VALUES(2,'e','2009-02-10 12:48:45.143')
    INSERT #MaxVal VALUES(2,'f','2009-02-10 13:48:45.143')
    INSERT #MaxVal VALUES(3,'g','2009-02-10 11:48:45.143')
    INSERT #MaxVal VALUES(3,'h','2009-02-10 14:48:45.143')




SELECT t.* FROM(
    SELECT id,MAX(SomeDate) AS MaxValue
    FROM #MaxVal
    WHERE SomeDate >='2009-02-10'
        AND SomeDate < '2009-02-11'
    GROUP BY id) x
    JOIN #MaxVal t ON x.id =t.id
    AND x.MaxValue =t.SomeDate

выход

id  VALUE   SomeDate
3   h   2009-02-10 14:48:45.143
2   f   2009-02-10 13:48:45.143
1   a   2009-02-10 14:48:45.143
1 голос
/ 10 февраля 2009

Для всех дней, попробуйте это:

SELECT FooId, Max(CreatedTime)
FROM Foo
GROUP BY FooId, cast(CreatedTime as int)

для данного дня, сделайте это:

SELECT FooId, Max(CreatedTime)
FROM Foo
WHERE CreatedTime >= '2000-01-01' and CreatedTime < '2000-01-02'
GROUP BY FooId, cast(CreatedTime as int)
1 голос
/ 10 февраля 2009

Разве не грубо удалить старое сообщение без предупреждения, потому что требования изменились? Разве вы не можете просто закрыть его, чтобы люди не задавались вопросом, что случилось?

В любом случае, вот обновленный ответ:

SELECT Foo.* 
FROM Foo
JOIN (
  SELECT FooId, MAX(CreatedTime) 
  FROM Foo Q
  -- Only change the dates in the next line.
  WHERE Q.CreatedTime >= '20000101' AND Q.CreatedTime < '20000102'
  GROUP BY Q.FooId, DATEADD(day, DATEDIFF(day, '19000101', Q.CreatedTime), '19000101')
) Q2 (FooID, CreatedTime) ON Q2.FooID = Foo.FooID AND Q2.CreatedTime = Foo.CreatedTime
ORDER BY FooID

Результаты

FooId   Data    CreatedTime
1   C   2000-01-02 12:25:00.000
2   B   2000-01-02 12:26:00.000
3   A   2000-01-02 12:00:00.000

DDL

CREATE TABLE Foo (FooId int NOT NULL, Data varchar(10), CreatedTime datetime NOT NULL)

INSERT INTO Foo VALUES (1, 'A', '2000-01-01 12:00:00')
INSERT INTO Foo VALUES (1, 'B', '2000-01-01 12:12:00')
INSERT INTO Foo VALUES (1, 'C', '2000-01-01 12:25:00')
INSERT INTO Foo VALUES (2, 'A', '2000-01-01 12:00:00')
INSERT INTO Foo VALUES (2, 'B', '2000-01-01 12:26:00')
INSERT INTO Foo VALUES (3, 'A', '2000-01-01 12:00:00')

INSERT INTO Foo VALUES (1, 'A', '2000-01-02 12:00:00')
INSERT INTO Foo VALUES (1, 'B', '2000-01-02 12:12:00')
INSERT INTO Foo VALUES (1, 'C', '2000-01-02 12:25:00')
INSERT INTO Foo VALUES (2, 'A', '2000-01-02 12:00:00')
INSERT INTO Foo VALUES (2, 'B', '2000-01-02 12:26:00')
INSERT INTO Foo VALUES (3, 'A', '2000-01-02 12:00:00')
0 голосов
/ 11 февраля 2009
select x.FooId, x.Data, x.CreatedTime
from (select FooId,
             Data,
             CreatedTime,
             row_number() over (partition by FooId
                                order by CreatedTime desc) as rn
       from Foo
       where CreatedTime >= ...
          and CreatedTime < ...) as x
where x.rn = 1
order by FooId
0 голосов
/ 10 февраля 2009

выберите top 1 *
из foo
, где CreatedTime между @today и @tuture
заказ по CreatedTime desc

(@ today и @tuture - заполнители для желаемого диапазона дат.)

0 голосов
/ 10 февраля 2009

Попробуйте это ...

select f1.FooID, f1.Data, f1.CreatedTime
from Foo f1
inner join
(
    select f2.FooID, max(f2.CreatedTime) as CreatedTime
    from Foo f2
    where f2.CreatedTime >= '2000-01-01' and f2.CreatedTime < '2000-01-02'
    group by f2.FooID
) f3
on f3.FooID = f1.FooID
and f3.CreatedTime = f1.CreatedTime
order by 1, 2, 3
0 голосов
/ 10 февраля 2009
select data 
 from fooTable 
 where CreatedTime between <beginning of day> and <end of day> 
 order by CreatedTime DESC 
 limit 1

Что-то в этом роде, возможно? Не проверено, с макушки головы.

0 голосов
/ 10 февраля 2009

Будет ли это работать в SqlServer2005?

SELECT FoodId, Data, CreatedTime WHERE CreatedTime=max(CreatedTime) GROUP BY FoodId, day(CreatedTime)
0 голосов
/ 10 февраля 2009

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

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