我希望能夠定位一條記錄,並取回該記錄,並在其兩側記錄可變數量的記錄。在一個查詢中檢索目標記錄和周圍的n條記錄?
就像說你有一個密鑰ID爲2356.所以你需要2356和2356前後的3條記錄,通過create_ts
(例如)的訂單。
我想知道是否有辦法在一個查詢(mysql)中做到這一點?
我希望能夠定位一條記錄,並取回該記錄,並在其兩側記錄可變數量的記錄。在一個查詢中檢索目標記錄和周圍的n條記錄?
就像說你有一個密鑰ID爲2356.所以你需要2356和2356前後的3條記錄,通過create_ts
(例如)的訂單。
我想知道是否有辦法在一個查詢(mysql)中做到這一點?
表(稱之爲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;
謝謝。我會試試看,然後回來。 – Spot 2012-02-14 18:18:14
好的,這可以工作(語法)。然而,輸出是第一個目標記錄,然後是_after_記錄,然後是_before_記錄。像這樣(_432_是目標):432,482,483,484,222,221,161(同樣注意_before_列表的順序)。我將如何解決這個問題? – Spot 2012-02-14 18:30:10
我更新了我的答案。我添加了'ORDER BY A.create_ts,A.id'。如果該命令不正確,請嘗試使用'ORDER BY A.id'。 – RolandoMySQLDBA 2012-02-14 18:37:48
如果你的選擇標準僅僅是ID:
SELECT *
FROM table
WHERE key_id <= target_id + 3
AND key_id >= target_id - 3
ORDER BY create_ts;
與周圍的目標記錄所需的記錄號替換3。
只有當你有一些連續的積分列時纔有效。 – 2012-02-14 18:08:16
我在這裏假設key_id是主自動增量鍵。但是它看起來像@Rolando推斷OP更想要的更正確。 :) – JYelton 2012-02-14 18:11:07
正確,你不希望這樣做,因爲只保證id是唯一的。無法保證訂單無論如何都是正確的。那爲什麼ORDER BY id ASC也完全錯了。按某些日期時間列進行排序會給出您可以信任的正確結果。 – 2012-02-14 18:17:53
這是什麼意思的記錄?你可以發佈一些虛擬記錄和你想要的輸出嗎?也是你的表的模式。謝謝.. – 2012-02-14 17:54:18