MySQL查询-自定义排序结果的前后行
我在StackOverflow中看到了其他类似的问题,但它们都基于自动递增ID,但我没有 我有一个类似这样的问题:MySQL查询-自定义排序结果的前后行,sql,mysql,sql-order-by,Sql,Mysql,Sql Order By,我在StackOverflow中看到了其他类似的问题,但它们都基于自动递增ID,但我没有 我有一个类似这样的问题: SELECT field_a, field_b from table where field_m = '100' and field_n = '200' order by field_x 这就导致了这种情况 field_a field_b ------------------- john 12 mar
SELECT field_a,
field_b
from table
where field_m = '100'
and field_n = '200'
order by field_x
这就导致了这种情况
field_a field_b
-------------------
john 12
marty 7
peter 2
carl 9
mark 11
bob 10
neil 1
louis 14
所以,我想要的是完成原始查询,并用一个查询在其中一个查询之前和之后获取记录。。。让我们说“卡尔”,但重要的是,在每种情况下都是不同的,我的意思是,其他时间需要在“鲍勃”之前和之后
那么,让我们说“卡尔”。。。我只需要创建一个SQL查询,在该查询中,我使用所描述的order by字段,并在字段\u a='carl'时获取前后行。您可以使用一个查询,但需要在两个集合之间合并以将结果合并在一起
SELECT * FROM
(
SELECT b.*
from tbl a
inner join tbl b on
b.field_m = '100'
and b.field_n = '200'
where a.field_m = '100'
and a.field_n = '200'
and a.field_a = 'carl'
and b.field_x <= a.field_x # comes before a sorted on x
order by b.field_x DESC
limit 2
) A
UNION
SELECT * FROM
(
SELECT b.*
from tbl a
inner join tbl b on
b.field_m = '100'
and b.field_n = '200'
where a.field_m = '100'
and a.field_n = '200'
and a.field_a = 'carl'
and b.field_x >= a.field_x # comes after a sorted on x
order by b.field_x ASC
limit 2
) B
其工作方式是将集合交叉到自身,其中a定位在“carl”处,b仅保留位置上位于集合1之前或之后的行。正确地排序这些表,然后使用
限制2
将包括“carl”和另一个(除非在允许重复的情况下,这也是“carl”)这对大表来说是相当沉重的,但是您可以使用排名和两次连接来获得上一个和下一个记录,然后只使用where来过滤它
SET @rank_prev = 0;
SET @rank_cur = 0;
SET @rank_next = 0;
SELECT
prev.field_a as prev_a,
prev.field_b as prev_b,
next.field_a as next_a,
next.field_b as next_b
FROM
(
SELECT
@rank_cur:=@rank_cur+1 AS rank,
field_a,
field_b
FROM dd
WHERE field_m = '100'
AND field_n = '200'
ORDER BY field_x
) as cur
INNER JOIN
(
SELECT
@rank_prev:=@rank_prev+1 AS rank,
field_a,
field_b
FROM dd
WHERE field_m = '100'
AND field_n = '200'
ORDER BY field_x
) as prev
ON prev.rank + 1 = cur.rank
INNER JOIN
(
SELECT
@rank_next:=@rank_next+1 AS rank,
field_a,
field_b
FROM dd
WHERE field_m = '100'
AND field_n = '200'
ORDER BY field_x
) as next
ON cur.rank+1 = next.rank
WHERE cur.field_a = 'carl';
在MySQL上工作嗨,你认为在一个有2000.000条记录的表中这会很快吗?如果你有一个复合索引(field_m,field_n,field_x),它会很好,每个分支只看一条记录对不起,但是那些子查询会返回“where field_m='100'和field_n='200'”记录集的第一行和第二行。。。不是我一直在测试的“carl”行的前后,这将与表上的自动递增ID字段一起工作。。。事实并非如此。。。“field_x
field_x
一无所知-它只是对记录进行排序!那么如何检查字段x
?您以前必须使用排名来查找carl的位置,但这不是一次性查询。您好,您认为在一个有2000.000条记录的表中这样做会很快吗?顺便说一下,我认为缺少连接:P@user311188我说它会在大桌子上很沉@user311188您是对的,连接丢失了,因为它不应该是交叉连接,而是内部连接。回答已更正。@user311188当然通过临时表执行此操作会快得多-选择进入表,排列记录(或在临时表中使用自动递增),查找carl的记录并输出上一个和下一个(秩-1,秩+1)。但您提出了一个一次性解决方案:)
SET @rank_prev = 0;
SET @rank_cur = 0;
SET @rank_next = 0;
SELECT
prev.field_a as prev_a,
prev.field_b as prev_b,
next.field_a as next_a,
next.field_b as next_b
FROM
(
SELECT
@rank_cur:=@rank_cur+1 AS rank,
field_a,
field_b
FROM dd
WHERE field_m = '100'
AND field_n = '200'
ORDER BY field_x
) as cur
INNER JOIN
(
SELECT
@rank_prev:=@rank_prev+1 AS rank,
field_a,
field_b
FROM dd
WHERE field_m = '100'
AND field_n = '200'
ORDER BY field_x
) as prev
ON prev.rank + 1 = cur.rank
INNER JOIN
(
SELECT
@rank_next:=@rank_next+1 AS rank,
field_a,
field_b
FROM dd
WHERE field_m = '100'
AND field_n = '200'
ORDER BY field_x
) as next
ON cur.rank+1 = next.rank
WHERE cur.field_a = 'carl';