2012-02-14 76 views
1

我希望能夠定位一條記錄,並取回該記錄,並在其兩側記錄可變數量的記錄。在一個查詢中檢索目標記錄和周圍的n條記錄?

就像說你有一個密鑰ID爲2356.所以你需要2356和2356前後的3條記錄,通過create_ts(例如)的訂單。

我想知道是否有辦法在一個查詢(mysql)中做到這一點?

+0

這是什麼意思的記錄?你可以發佈一些虛擬記錄和你想要的輸出嗎?也是你的表的模式。謝謝.. – 2012-02-14 17:54:18

回答

2

表(稱之爲MYTABLE)必須有

ALTER TABLE mytable ADD INDEX create_ts_id_index (create_ts,id); 

你顯然需要兩個查詢回暖所需的密鑰對create_ts一個複合索引和id:3號之前,該ID本身,3號之後。

這是7個ID。

此查詢拾取4個鍵(ID + 3後)

SELECT create_ts,id FROM mytable WHERE id >= 2356 ORDER BY create_ts LIMIT 4; 

此查詢拾取4個鍵(ID + 3之前)

SELECT create_ts,id FROM mytable WHERE id < 2356 ORDER BY create_ts DESC LIMIT 4; 

A中的兩個查詢的UNION應消除一個id的副本2356

讓我們結合這些並執行它的INNER JOIN到我的表

SELECT B.* FROM 
(
    SELECT * FROM 
    (SELECT create_ts,id FROM mytable 
    WHERE id >= 2356 ORDER BY create_ts 
    LIMIT 4) AA 
    UNION 
    (SELECT create_ts,id FROM mytable 
    WHERE id <= 2356 ORDER BY create_ts DESC 
    LIMIT 4) 
) A 
INNER JOIN mytable B USING (create_ts,id) 
ORDER BY A.create_ts,A.id; 

子查詢A應該只有7個鍵。一旦檢索到這7個鍵,INNER JOIN應該很快。

無論何時您需要之前的N個密鑰和此查詢後的N個密鑰,只需使用LIMIT N+1即可。

我會建議這種方法,因爲我們既不能假定3個鍵返回是id-3,也不是假設id + 3之後的3個鍵。如果表中出於任何原因在ID中存在空白,則尤其如此。

試試吧!

CAVEAT:我沒有嘗試過。這就是你想要的算法。 MySQL語法可能允許或不允許。它的語法不正確,我會嘗試構造一個例子並修正語法。

爲了以防萬一,這裏是一個更穩定的方法。

CREATE TABLE create_ts_ids SELECT create_ts,id FROM mytable WHERE 1=2; 
ALTER TABLE create_ts_ids ADD PRIMARY KEY (id); 
INSERT INTO create_ts_ids 
SELECT create_ts,id FROM mytable 
WHERE id >= 2356 ORDER BY create_ts LIMIT 4; 
INSERT IGNORE INTO create_ts_ids 
SELECT create_ts,id FROM mytable 
WHERE id <= 2356 ORDER BY create_ts DESC LIMIT 4; 
SELECT B.* FROM create_ts_ids A 
INNER JOIN mytable B USING (create_ts,id) 
ORDER BY A.create_ts,A.id; 
+0

謝謝。我會試試看,然後回來。 – Spot 2012-02-14 18:18:14

+0

好的,這可以工作(語法)。然而,輸出是第一個目標記錄,然後是_after_記錄,然後是_before_記錄。像這樣(_432_是目標):432,482,483,484,222,221,161(同樣注意_before_列表的順序)。我將如何解決這個問題? – Spot 2012-02-14 18:30:10

+0

我更新了我的答案。我添加了'ORDER BY A.create_ts,A.id'。如果該命令不正確,請嘗試使用'ORDER BY A.id'。 – RolandoMySQLDBA 2012-02-14 18:37:48

-1

如果你的選擇標準僅僅是ID:

SELECT * 
FROM table 
WHERE key_id <= target_id + 3 
AND key_id >= target_id - 3 
ORDER BY create_ts; 

與周圍的目標記錄所需的記錄號替換3。

+0

只有當你有一些連續的積分列時纔有效。 – 2012-02-14 18:08:16

+0

我在這裏假設key_id是主自動增量鍵。但是它看起來像@Rolando推斷OP更想要的更正確。 :) – JYelton 2012-02-14 18:11:07

+0

正確,你不希望這樣做,因爲只保證id是唯一的。無法保證訂單無論如何都是正確的。那爲什麼ORDER BY id ASC也完全錯了。按某些日期時間列進行排序會給出您可以信任的正確結果。 – 2012-02-14 18:17:53

相關問題