Extracting rows with a consecutive pattern that exceeds a threshold - mysql

I currently have this set of data.
Id
pattern
1
1
2
2
3
1
4
2
5
3
6
4
7
1
8
2
9
1
10
2
11
3
I have ids sorted ascending, and a column called pattern. The goal is to retrieve only the rows with a consecutive pattern >=3 down the table.
So the result would be:
Id
pattern
3
1
4
2
5
3
6
4
9
1
10
2
11
3
Since the pattern for Ids 3-6 have consecutively reached >=3, we will return these 4 rows.
Same goes for Ids 9-11.
Id 1-2 did not reach the threshold of 3. Same for Id 7-8.
Would appreciate any help!

Use SUM() window function to create the groups of the sequences and with MAX() window function check the max pattern in each group:
SELECT Id, pattern
FROM (
SELECT *, MAX(pattern) OVER (PARTITION BY grp) max_pattern
FROM (
SELECT *, SUM(pattern = 1) OVER (ORDER BY Id) grp
FROM tablename
) t
) t
WHERE max_pattern >= 3;
Or, with a correlated subquery, for versions of MySql that do not support window functions:
SELECT t1.*
FROM tablename t1
WHERE (SELECT t2.pattern FROM tablename t2 WHERE t2.Id = t1.Id + (3 - t1.pattern)) = 3;
See the demo.

Related

MySQL Group by consecutive values and count

I have a table that looks like this
id
1
2
4
5
6
10
11
So a bunch of consecutive values, an unknown number of absent fields and then other consecutive values.
What I am trying to achieve is to get
id
stint
1
0
2
0
4
1
5
1
6
1
10
2
11
2
By incrementing every time the number of the stint, which I can later use for summing over other columns.
Is it possible? Thanks
If your MySQL version support window function.
You can try to use LAG window function in subquery to get previous id column, then use SUM condition aggregate window function.
Query #1
SELECT Id,
SUM(id - n_Id > 1) OVER(ORDER BY id) stint
FROM (
SELECT *,LAG(id,1,id) OVER(ORDER BY id) n_Id
FROM T
) t1
Id
stint
1
0
2
0
4
1
5
1
6
1
10
2
11
2
View on DB Fiddle

How to select MAX/MIN in MySQL with dynamic between clause

Assume a table with two columns t (a string with TimeStamps) and v (decimal). For each t I want to query the MAXIMUM of the value v in a certain range defined by the current t.
How can i transfer below statement to proper SQL?
select t, max(v for t between t-2MIN and t+2min) from table_name;
Example:
Assume below table.
t
v
1
3
2
2
3
5
4
4
5
8
6
1
I need an SQL-statement which gives me (for e.g. a width 2: max(v for t between t-2 and t+2)) the following result
t
v
1
5
2
5
3
8
4
8
5
8
6
8
Join the table with itself using the range as the joining condition.
SELECT t1.t, MAX(t2.v) AS max_v
FROM table_name AS t1
JOIN table_name AS t2 ON t2.t BETWEEN t1.t - 2 AND t1.t + 2
GROUP BY t1.t
If you use MySQL 8.x I think you should be able to do it using window functions, but I don't know the proper syntax for this.
In MySql 8 you can use a MAX OVER with rows between a range.
select t
, max(v) over (order by t rows
between 2 preceding and 2 following) v
from table_name

How to select X consecutive numbers of rows meeting a condition

I the following table:
ID TIMESLOT_ID SLOTS_AVAILABLE
1 1 10
2 3 2
3 8 3
4 9 10
5 2 10
6 6 10
7 4 10
I want to perform a query where I can get all rows where SLOTS_AVAILABLE is equal or greater than (user_input_1) AND the next (user_input_2) consecutive rows following to that one meet the same condition (SLOTS_AVAILABLE is equal or greater than (user_input_1))
So if (user_input_1) is 3 and (user_input_2) is 3 the result would be:
ID TIMESLOT_ID SLOTS_AVAILABLE
3 8 3
4 9 10
Hmmm . . . If I understand correctly, you want window functions:
select t.*
from (select t.*,
sum(case when slots_available >= :user_input_1 then 1 else 0 end) over
(order by id
rows between current row and :user_input_2 following
) as cnt
from t
) t
where cnt = :user_input_2 + 1;
This requires MySQL 8+.
Here is a db<>fiddle.

Selecting sum of three consecutive values in a same row in the table in MYSQL

plz refer the table to provide the sql query to get result like that.
id value
1 10
2 15
3 30
4 10
5 11
6 12
Desired output:
id value
1 55
2 33
http://sqlfiddle.com/#!9/21cbc8
Divide id by 3, round it up, group it (with a sum):
SELECT
ceiling(id / 3) AS NewID,
sum(Value) AS SumValue
FROM MyTable
GROUP BY ceiling(id / 3)
With a variable:
SET #GroupVar = 3; -- Set this number to whatever you want to group by
SELECT
ceiling(id / #GroupVar) AS NewID,
sum(Value) AS SumValue
FROM MyTable
GROUP BY ceiling(id / #GroupVar);

Identify consecutive rows

I have a table in the following format:
cId seq
--- ---
A 1
A 2
A 4
A 5
B 8
B 9
A 12
A 13
I would like to write a query that would produce another table that looks like:
cId seq consecutive
--- --- -----------
A 1 1
A 2 1
A 4 2
A 5 2
B 8 3
B 9 3
A 12 4
A 13 4
What I am trying to do is identify consecutive seq values that have the same cId and then number them.
I was thinking of using Lag function to determine the previous seq value and then setting the consecutive column but don't know how to increment the value when I encounter the next break.
SELECT [cId],
[Seq],
CASE WHEN [Seq] - 1 = LAG([Seq], 1, [Seq]) OVER ( ORDER BY [Seq]) THEN 1
ELSE 2 END as consecutive
FROM #ConsecutiveData
This query will put a 2 next to the start of each sequence. That's the closest I have come.
I think author is not using MySQL, since, as far as I know, there is no LAG function in MySQL.
Below is a possible solution for MSSQL:
SELECT
cid,
seq,
DENSE_RANK() OVER (ORDER BY seq - row_num) consecutive
FROM (
SELECT
cid,
seq,
ROW_NUMBER() OVER (ORDER BY seq) row_num
FROM
test_table
) data
;
Check at SQLFiddle: SQLFiddle Example