Select MySQL 中特定值下的连续行
Select consecutive rows under a certain value in MySQL
选择列低于特定值的连续行
我有一个 table 包含以下数据:
crashID crash
-----------------------
1 189
2 144
3 8939
4 748
5 988
6 102
7 392
8 482
9 185
10 101
我想要 select 崩溃值低于特定阈值的最长连续行。假设这个例子是 500。
如何在单个 MySQL 查询中执行此操作? (v8.0.1)
期望的输出是这样的:
crashID crash
------------------
6 102
7 392
8 482
9 185
10 101
您可以尝试使用间隙和孤岛方法来解决它,假设每个崩溃的 lte 500 都是一个孤岛,然后找到最大的孤岛:
SET @threshold = 500;
WITH cte1 AS (
SELECT
crashID,
CASE WHEN crash <= @threshold THEN 1 ELSE 0 END AS island,
ROW_NUMBER() OVER (ORDER BY crashID) rn1,
ROW_NUMBER() OVER (PARTITION BY CASE WHEN crash <= @threshold THEN 1 ELSE 0 END ORDER BY crashID) rn2
FROM t
), cte2 AS (
SELECT MIN(crashID) AS fid, MAX(crashID) AS tid
FROM cte1
WHERE island = 1
GROUP BY rn1 - rn2
ORDER BY COUNT(*) DESC
LIMIT 1
)
SELECT *
FROM t
WHERE crashID BETWEEN (SELECT fid FROM cte2) AND (SELECT tid FROM cte2);
这是一种方法,适用于 MySQL 的旧版本...
此解决方案假定第一名没有关系...
SELECT m.*
FROM my_table m
JOIN
( SELECT MIN(crash_id) range_start
, MAX(crash_id) range_end
FROM
( SELECT x.*
, CASE WHEN FLOOR(crash/500) * 500 = 0 AND @prev = FLOOR(crash/500) * 500 THEN @i:=@i ELSE @i:=@i+1 END i
, @prev:=FLOOR(crash/500)*500 prev
FROM my_table x
, (SELECT @prev:=null,@i:=0) vars
ORDER
BY crash_id
) a
GROUP
BY i
ORDER
BY COUNT(*) DESC LIMIT 1
) n
ON m.crash_id BETWEEN n.range_start AND n.range_end;
选择列低于特定值的连续行
我有一个 table 包含以下数据:
crashID crash
-----------------------
1 189
2 144
3 8939
4 748
5 988
6 102
7 392
8 482
9 185
10 101
我想要 select 崩溃值低于特定阈值的最长连续行。假设这个例子是 500。
如何在单个 MySQL 查询中执行此操作? (v8.0.1)
期望的输出是这样的:
crashID crash
------------------
6 102
7 392
8 482
9 185
10 101
您可以尝试使用间隙和孤岛方法来解决它,假设每个崩溃的 lte 500 都是一个孤岛,然后找到最大的孤岛:
SET @threshold = 500;
WITH cte1 AS (
SELECT
crashID,
CASE WHEN crash <= @threshold THEN 1 ELSE 0 END AS island,
ROW_NUMBER() OVER (ORDER BY crashID) rn1,
ROW_NUMBER() OVER (PARTITION BY CASE WHEN crash <= @threshold THEN 1 ELSE 0 END ORDER BY crashID) rn2
FROM t
), cte2 AS (
SELECT MIN(crashID) AS fid, MAX(crashID) AS tid
FROM cte1
WHERE island = 1
GROUP BY rn1 - rn2
ORDER BY COUNT(*) DESC
LIMIT 1
)
SELECT *
FROM t
WHERE crashID BETWEEN (SELECT fid FROM cte2) AND (SELECT tid FROM cte2);
这是一种方法,适用于 MySQL 的旧版本... 此解决方案假定第一名没有关系...
SELECT m.*
FROM my_table m
JOIN
( SELECT MIN(crash_id) range_start
, MAX(crash_id) range_end
FROM
( SELECT x.*
, CASE WHEN FLOOR(crash/500) * 500 = 0 AND @prev = FLOOR(crash/500) * 500 THEN @i:=@i ELSE @i:=@i+1 END i
, @prev:=FLOOR(crash/500)*500 prev
FROM my_table x
, (SELECT @prev:=null,@i:=0) vars
ORDER
BY crash_id
) a
GROUP
BY i
ORDER
BY COUNT(*) DESC LIMIT 1
) n
ON m.crash_id BETWEEN n.range_start AND n.range_end;