mysql获取目标行号±2排

p8ekf7hl  于 2021-08-13  发布在  Java
关注(0)|答案(2)|浏览(397)

我有一个 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 ± 两排。
我使用的是MySQL5.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;

这是一个可怕的查询,如果经常这样做。
有没有办法让它变轻?
因为它是MySQL5.7,所以我试着给它添加一个倒过来的值列 value 列,因为在上跳过索引 DESC ,但没有多大帮助。
我也试着通过 ROW_NUMBER 窗口函数,作为在MySQL8上的一个实验,但是效果不是很好。。。
光标在这种情况下有用吗?

rdrgkggo

rdrgkggo1#

在mysql 8.0中,一个常见的表表达式在这里可能很方便:

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'
cuxqih21

cuxqih212#

鉴于

+-----+------------+
| 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)

相关问题