Mysql获取目标行号±2行
Posted
技术标签:
【中文标题】Mysql获取目标行号±2行【英文标题】:Mysql get target row number ±2 rows 【发布时间】:2020-09-09 12:33:18 【问题描述】:我有一个My_Table
,看起来像这样:
PK1 | PK2 | Value | Date_Changed
还有一个基本上可以做到这一点的查询:
SELECT
PK1,
PK2,
Value,
ROW_NUMBER() OVER ( ORDER BY Value desc, Date_Changed ASC) AS position
FROM My_Table
where PK1 = 1;
然后我从查询结果中得到position
,其中PK2 = myValue
。
使用position
,我返回到那个查询,并得到带有position
± 2 行的行。
我使用的是 mysql 5.7,所以我必须这样做:
SET @rownum = 0;
SET @bingo = NULL;
SELECT p.PK2 AS PK2,
p.Value,
p_o.Position
FROM My_Table p
JOIN (
SELECT PK1,
PK2,
@rownum := @rownum + 1 AS Position,
CASE
WHEN PK2 = param_PK2
THEN @bingo := @rownum
ELSE 0
END AS bbb
FROM My_Table
WHERE PK1 = param_PK1
ORDER BY value DESC, Date_Changed ASC
) p_o
ON p.PK1 = p_o.PK1
AND p.PK2 = p_o.PK2
AND @bingo IS NOT NULL
AND Position < @bingo + offset
AND Position > @bingo - offset
ORDER BY p_o.Position;
如果经常这样做,这是一个可怕的查询。
有什么办法可以让它变轻吗?
由于它是 Mysql 5.7,我尝试在 value
列中添加一个反转值列,因为在 DESC
上跳过了索引,但它并没有太大帮助。
我也尝试通过ROW_NUMBER
窗口函数来做,作为mysql 8的实验,但结果不是很好......
在这种情况下光标会有所帮助吗?
【问题讨论】:
【参考方案1】:给定
+-----+------------+
| id | dte |
+-----+------------+
| 846 | 2020-04-26 |
| 847 | 2020-04-27 |
| 848 | 2020-04-28 |
| 849 | 2020-04-29 |
| 850 | 2020-04-30 |
| 851 | 2020-05-01 |
| 852 | 2020-05-02 |
| 853 | 2020-05-03 |
| 854 | 2020-05-04 |
+-----+------------+
9 rows in set (0.002 sec)
select id,dte
from dates
where dte = '2020-05-01'
union
(select id,dte
from dates
where dte < '2020-05-01'
order by dte desc limit 2
)
union all
(select id,dte
from dates
where dte > '2020-05-01'
order by dte limit 2
)
order by dte;
+-----+------------+
| id | dte |
+-----+------------+
| 849 | 2020-04-29 |
| 850 | 2020-04-30 |
| 851 | 2020-05-01 |
| 852 | 2020-05-02 |
| 853 | 2020-05-03 |
+-----+------------+
5 rows in set (0.004 sec)
【讨论】:
【参考方案2】:在 MySQL 8.0 中,common-table-expression 在这里可能会派上用场:
with cte as (
select t.*, row_number() over(order by value desc, date_changed desc) position
from mytable t
)
select c.*
from cte c
inner join cte c1 on c.rn between c1.rn - 2 and c1.rn + 2
where c1.pk1 = 1 and c1.pk2 = 'myvalue'
【讨论】:
以上是关于Mysql获取目标行号±2行的主要内容,如果未能解决你的问题,请参考以下文章