检索目标记录&和一个查询中的周围n条记录?

时间:2012-02-14 17:47:53

标签: mysql

我希望能够定位一条记录,并获取该记录,并在其每一侧记录可变数量的记录。

比如说你的密钥ID是2356.所以你需要2356和2356之前和之后的3条记录,并在create_ts上订购(例如)。

我想知道是否有办法在一个查询(mysql)中执行此操作?

2 个答案:

答案 0 :(得分:2)

表(称之为mytable)必须在create_ts和id

上有一个复合索引
ALTER TABLE mytable ADD INDEX create_ts_id_index (create_ts,id);

你显然需要两个查询来获取所需的密钥:3在id之前,id本身,3在id之后。

那是7个ids。

此查询选择4个键(id + 3 after)

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;

两个查询的UNION应该删除id 2356

的副本

让我们将这些结合起来并执行它的INNER JOIN到mytable

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,也不能假设3键后面是id + 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;

答案 1 :(得分:-1)

如果您的选择标准只是id:

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

将3替换为目标记录周围所需的记录数。