2010-06-18 64 views
2

一個棘手的SQL問題(我使用的是postgres)。SQL - 過去X天每天插入第一行

我需要在過去X天每天插入第一行。我的一列是一個時間戳,我插入時間,另一列是行ID。

如果不可能每天插入第一行,我至少需要一個唯一的;過去x天每天一行。

有什麼建議嗎?

感謝

okie

回答

4

你可能想嘗試像以下(在MySQL的測試,但我想這應該很容易地移植到Postgres的):

SELECT  l.id, l.timestamp, l.value 
FROM  log l 
INNER JOIN (
      SELECT MIN(timestamp) first_timestamp 
      FROM  log 
      GROUP BY DATE(timestamp) 
      ) sub_l ON (sub_l.first_timestamp = l.timestamp) 
WHERE  l.timestamp > DATE_ADD(NOW(), INTERVAL -30 DAY); 

注意這假定您的時間戳是唯一的。

測試案例(在MySQL):

CREATE TABLE log (id int, timestamp datetime, value int); 

INSERT INTO log VALUES (1, '2010-06-01 02:00:00', 100); 
INSERT INTO log VALUES (2, '2010-06-01 03:00:00', 200); 
INSERT INTO log VALUES (3, '2010-06-01 04:00:00', 300); 
INSERT INTO log VALUES (4, '2010-06-02 02:00:00', 400); 
INSERT INTO log VALUES (5, '2010-06-02 03:00:00', 500); 
INSERT INTO log VALUES (6, '2010-06-03 02:00:00', 600); 
INSERT INTO log VALUES (7, '2010-06-04 02:00:00', 700); 
INSERT INTO log VALUES (8, '2010-06-04 03:00:00', 800); 
INSERT INTO log VALUES (9, '2010-06-05 05:00:00', 900); 
INSERT INTO log VALUES (10, '2010-06-05 03:00:00', 1000); 

結果:

+------+---------------------+-------+ 
| id | timestamp   | value | 
+------+---------------------+-------+ 
| 1 | 2010-06-01 02:00:00 | 100 | 
| 4 | 2010-06-02 02:00:00 | 400 | 
| 6 | 2010-06-03 02:00:00 | 600 | 
| 7 | 2010-06-04 02:00:00 | 700 | 
| 10 | 2010-06-05 03:00:00 | 1000 | 
+------+---------------------+-------+ 
5 rows in set (0.00 sec) 
+0

如果您在派生表中添加了min(ID),並且在連接條件中添加了ID子句,則可以解決「假設您的時間戳是唯一的」。 – potatopeelings 2010-06-18 05:43:00

+0

@potatopeelings:我不認爲這很容易。在上面的測試用例中,'SELECT MIN(timestamp),MIN(id)FROM log GROUP BY DATE(timestamp)'會返回最後一行作爲'2010-06-05 03:00:00 | 9'。如果我要爲JOIN條件添加一個ID子句,它將不匹配,因爲表中沒有包含timestamp =''2010-06-05 03:00:00'AND id ='9''的行。 ..(這至少在MySQL中)。 – 2010-06-18 06:09:37

+0

哦,是的,你說得對。我的錯。它必須是一個子查詢或加入,才能從每天使用最低時間戳的ID中排除最低ID。就像你指出的那樣 - 並不像MIN,MIN那麼簡單。抱歉! – potatopeelings 2010-06-18 07:14:39

3

瓦薩洛先生,你是一個搖滾明星。

它工作得很好。這裏是Postgres的版本的SQL的:

SELECT l.id, l.timestamp, l.value 
FROM log l 
INNER JOIN (
      SELECT MIN(timestamp) AS first_timestamp 
      FROM  log 
      GROUP BY DATE(timestamp) 
) sub_l ON (sub_l.first_timestamp = l.timestamp) 
WHERE  l.timestamp > NOW() - INTERVAL '30 DAY' ORDER BY l.timestamp; 

沒有得到需要的最小ID,因爲我不能保證插件將直接按時間順序(時間標記是不是真的插入的時間,但數據中存在時間戳,並且數據包可能失序)。

我非常感謝幫助。感謝您看看這個。

+0

對不起,應該說'SELECT MIN(timestamp)AS first_timestamp' – 2010-06-18 13:23:38

+0

我很高興這有幫助。感謝您發佈Postgres版本:)我已經編輯了您的答案,修正了您所建議的'MIN(timestamp)AS ...'部分。 – 2010-06-18 16:30:14