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
Related
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
I have a table where the count of a specific data goes up to 5 and then rolls over to 0, I would like to query the table which shows the actual count as shown below
Desired OutPut:
Dev_count
Actual_Count
1
1
2
2
3
3
4
4
5
5
0
6
1
7
2
8
3
9
4
10
5
11
0
12
I tried using a Trigger to update an additional column with actual count using below SQL script
CREATE TRIGGER insert_continuous_count BEFORE INSERT ON x_table
FOR EACH ROW SET
NEW.continuous_count = (SELECT continuous_count
FROM x_table
where device_id = NEW.device_id
order by No DESC LIMIT 1
) + 1;
Then I read somewhere that the trigger cannot update the same table which is already being used (for reading or writing) by the statement that invoked the function or trigger.
Is there any easier way to get the desired output?
I think you need something like this :
select dev_count,
#row_number:= #row_number + 1 as Actual_Count
from test_tbl
cross join (select #row_number := 0) x;
Demo: https://www.db-fiddle.com/f/7yUJcuMJPncBBnrExKbzYz/139
In MySQL 8+ you can use ROW_NUMBER function:
SELECT
dev_count,
ROW_NUMBER() OVER () as rn
FROM test_tbl
ORDER BY rn;
Demo: https://www.db-fiddle.com/f/7yUJcuMJPncBBnrExKbzYz/144
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.
I have an SQL table with "start" and "end" columns: for the sake of simplicity, let's assume they are integers between 1 and 10. I would like to somehow obtain a histogram of the values between "start" and "end".
For instance, given the following rows:
start
end
3
8
4
9
I would like to obtain the following histogram:
time
count
1
0
2
0
3
1
4
2
5
2
6
2
7
2
8
2
9
1
10
0
I really have no idea where to start looking in the SQL syntax to get that result -- maybe an inner join?
You can use a recursive CTE to generate times -- if you don't have a handy tally or numbers table. Then join and aggregate:
with recursive cte as (
select 1 as t
union all
select t + 1
from cte
where t < 10
)
select cte.t,
(select count(*)
from t
where cte.t between t.start and t.end
) as cnt
from cte;
Here is a db<>fiddle.
I have a strange error first time seing such results maybe someone else also found how to overpass such odd error.
I have a table structure like this :
|id|uid|test1|test2|rid|
1 1 - - 1
2 1 - - 1
3 2 - - 2
4 2 - - 2
5 3 - - 3
6 3 - - 3
7 4 - - 4
8 4 - - 4
----------------------------
as "-" are varchar data all other columns are integers
My query with the odd results is this :
SELECT COUNT(uid) AS COUNT,
id AS ID,
uid AS InqID,
test1 AS A,
test2 AS B
FROM test_table
WHERE rid = (X)
GROUP BY uid
ORDER BY id DESC
As results i get
if (X) = 1 or 3 it shows me the correct last id number (2 id for 1 and 6 id for 3)
but if (X) is 2 or 4 it shows me the first in row id number (3 id for 2 instead of 4 and 7 id for 4 instead of 8)
Can anyone tell me why i get the correct results only as singles in rid and not at even numbers of rid column or how at least this query will work as it has to ?
Thank you all in advance
Use MAX(id) instead of ORDER BY.
SELECT COUNT(uid) AS COUNT, MAX(id) AS ID, uid AS InqID, test1 AS A, test2 AS B
FROM test_table
WHERE rid = (X)
GROUP BY uid