假设我有一张如下所示的表格:
mytable
category | begintime
---------|----------------------
cat1 | 2016-09-25 15:00:00
cat2 | 2016-09-25 16:00:00
cat1 | 2016-09-25 17:30:00
cat3 | 2016-09-25 19:00:00
cat1 | 2016-09-25 20:00:00
: :
请注意,它没有 ID 号,begintime
列是我的主键。
最后,我想选择由某个类别包围的所有行,即选择上一行的类别为 @catBefore
且类别为的所有行下一行是@catAfter
。
例如,我想要的是这样的:
SELECT * FROM mytable WHERE previousRow.category = 'cat1' AND nextRow.category = 'cat1'
结果
SELECT * FROM ...
category | begintime
---------|----------------------
cat2 | 2016-09-25 16:00:00
cat3 | 2016-09-25 19:00:00
: :
这里的previousRow
和nextRow
似乎无法定义。
想法
我已经尝试了一些方法,但还没有任何结果。我的想法之一是首先选择上一个和下一个类别作为新列,例如:
SELECT mytable.*,
previousRow.category AS prevCat,
nextRow.category AS nextCat
FROM mytable, [stuff-I-don't-know]
结果
SELECT mytable.* ...
category | begintime | prevCat | nextCat
---------|----------------------|---------|---------
cat1 | 2016-09-25 15:00:00 | null | cat2
cat2 | 2016-09-25 16:00:00 | cat1 | cat1
cat1 | 2016-09-25 17:30:00 | cat2 | cat3
cat3 | 2016-09-25 19:00:00 | cat1 | cat1
cat1 | 2016-09-25 20:00:00 | cat3 | ...
: :
然后使用 WHERE
子句进行过滤。
这个想法是否可行,或者可以通过其他方式实现吗?
最佳答案
一种方法使用相关子查询。如果您确实有主键声明,那么从性能角度来看,这应该没问题:
select t.*
from (select t.*,
(select t2.category
from mytable t2
where t2.begintime < t.begintime
order by begintime desc
limit 1
) as prev_category,
(select t2.category
from mytable t2
where t2.begintime > t.begintime
order by begintime asc
limit 1
) as next_category
from mytable t
) t
where prev_category = @cat1 and next_category = @cat2;
编辑:
您可以使用变量来做到这一点:
select t.*
from (select t.*,
(@pn := (case when (@pcy := @pn) = NULL then -1 -- never gets here
when (@pn := category) = NULL then -1 -- never gets here
else @pcy
end)
) as next_category
from (select t.*,
(@pc := (case when (@pcx := @pc) = NULL then -1 -- never gets here
when (@pc := category) = NULL then -1 -- never gets here
else @pcx
end)
) as prev_category
from t cross join
(select @pc := '') params
order by t.begintime
) t cross join
(select @pn := '') params
order by t.begintime desc
) t
where prev_category = @cat1 and next_category = @cat2;
关于MySQL 根据上一行和下一行选择行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39688517/