How can I find duplicate consecutive values in this table?
Use the lead and lag analytic functions.
create table t3 (d number, v number);
insert into t3(d, v) values(1, 1);
insert into t3(d, v) values(2, 2);
insert into t3(d, v) values(3, 2);
insert into t3(d, v) values(4, 3);
insert into t3(d, v) values(5, 2);
insert into t3(d, v) values(6, 3);
insert into t3(d, v) values(7, 4);
select d, v, case when v in (prev, next) then '*' end match, prev, next from (
select
d,
v,
lag(v, 1) over (order by d) prev,
lead(v, 1) over (order by d) next
from
t3
)
order by
d
;
Matching neighbours are marked with * in the match column,
Count consecutive duplicate values in SQL
I am going to presume that id
is unique and increasing. You can get counts of consecutive values by using the different of row numbers. The following counts all sequences:
select grp, value, min(id), max(id), count(*) as cnt
from (select t.*,
(row_number() over (order by id) - row_number() over (partition by value order by id)
) as grp
from table t
) t
group by grp, value;
If you want the longest sequence of 0s:
select top 1 grp, value, min(id), max(id), count(*) as cnt
from (select t.*,
(row_number() over (order by id) - row_number() over (partition by value order by id)
) as grp
from table t
) t
group by grp, value
having value = 0
order by count(*) desc
Count consecutive duplicate values by group
This is a gap-and-islands problem. One method is the difference of row_number()
s to identify the groups.
select t.*,
dense_rank() over (partition by id order by (seqnum - seqnum_value), value) as grp,
row_number() over (partition by id, (seqnum - seqnum_value), value order by date) as grp_seqnum
from (select t.*,
row_number() over (partition by id order by date) as seqnum,
row_number() over (partition by id, value order by date) as seqnum_v
from t
) t;
This is a bit tricky to understand the first time you see it. If you run the subquery and stare at the results long enough, you'll get why the difference is constant for adjacent values.
EDIT:
I think Jorge is right. Your data doesn't have the same value repeated, so you can just do:
select t.*,
row_number() over (partition by id, value order by date) as grp_seqnum
from t;
Oracle finding duplicate rows that are consecutive for a given field
The simple solution to only SELECT
the relevant data is to use LAG()
. For example:
select *,
from (
select t.*,
lag(widgetdesc) over(
partition by widgetid
order by timestampOfTableUpdate
) as prev_desc
from my_table t
) x
where widgetdesc <> prev_desc
Counting consecutive duplicate field with SQL
This is a 'Gaps and Islands' problem, you can try like following.
;with cte
as (select *,
dateadd(day, -row_number()
over (partition by status, personid
order by [date] ), [date]) AS grp
FROM @table
)
,cte1
AS (select *,row_number() over(partition by personid, grp,status order by [date]) rn,
count(*) over(partition by personid, grp) ct
from cte
)
select ct as count, personid
from cte1
where rn=1
Online Demo
Note: You might not get the rows in same sequence as you don't have any column which can be used for ordering the way you showed in the desired output.
How to select sequential duplicates in SQL Server
This is a gaps and islands style problem, but instead of using two row_numbers()
, we use the id
and row_number()
in the innermost subquery. Followed by count() over()
to get the count per grp
, and finally return those with a cnt > 1
.
select id, companyname
from (
select
id
, companyName
, grp
, cnt = count(*) over (partition by companyname, grp)
from (
select *
, grp = id - row_number() over (partition by companyname order by id)
from
companies
) islands
) d
where cnt > 1
order by id
rextester demo: http://rextester.com/ACP73683
returns:
+----+-------------+
| id | companyname |
+----+-------------+
| 3 | pigs ltd |
| 4 | pigs ltd |
| 5 | cats ltd |
| 6 | cats ltd |
+----+-------------+
Counting consecutive duplicate records with SQL
(Edited after comment)
You can do that by assigning a "head" number to each group of consecutive values. After that you select the head number for each row, and do an aggregate per head.
Here's an example, with CTE's for readability:
WITH
OrderedTable as (
select value, rownr = row_number() over (order by userid, id)
from YourTable
where userid = 2287
),
Heads as (
select cur.rownr, CurValue = cur.value
, headnr = row_number() over (order by cur.rownr)
from OrderedTable cur
left join OrderedTable prev on cur.rownr = prev.rownr+1
where IsNull(prev.value,-1) != cur.value
),
ValuesWithHead as (
select value
, HeadNr = (select max(headnr)
from Heads
where Heads.rownr <= data.rownr)
from OrderedTable data
)
select Value, [Count] = count(*)
from ValuesWithHead
group by HeadNr, value
order by count(*) desc
This will output:
Value Count
2 4
3 3
1 2
2 1
2 1
7 1
Use "top 1" to select the first row only.
Here's my query to create the test data:
create table YourTable (
id int primary key,
userid int,
variable varchar(25),
value int
)
insert into YourTable (id, userid, variable, value) values (3115, 2287, 'votech05', 2)
insert into YourTable (id, userid, variable, value) values (3116, 2287, 'comcol05', 1)
insert into YourTable (id, userid, variable, value) values (3117, 2287, 'fouryr05', 1)
insert into YourTable (id, userid, variable, value) values (3118, 2287, 'none05', 2)
insert into YourTable (id, userid, variable, value) values (3119, 2287, 'ocol1_05', 2)
insert into YourTable (id, userid, variable, value) values (3120, 2287, 'disnone', 2)
insert into YourTable (id, userid, variable, value) values (3121, 2287, 'dissense', 2)
insert into YourTable (id, userid, variable, value) values (3122, 2287, 'dismobil', 3)
insert into YourTable (id, userid, variable, value) values (3123, 2287, 'dislearn', 3)
insert into YourTable (id, userid, variable, value) values (3124, 2287, 'disment', 3)
insert into YourTable (id, userid, variable, value) values (3125, 2287, 'disother', 2)
insert into YourTable (id, userid, variable, value) values (3126, 2287, 'disrefus', 7)
Related Topics
Executing a Stored Procedure Within a Stored Procedure
SQL Statements with Equals VS In
Efficient Way to Update All Rows in a Table
How to Change the Primary Key to Be Non-Clustered
Is There a Tool for Refactoring SQL, a Bit Like a Resharper for SQL
How to Find Values in All Caps in SQL Server
Checking Whether an Item Does Not Exist in Another Table
Modify Materialized View Query
SQL Query for Point-In-Polygon Using Postgresql
Bigquery: How to Group and Count Rows Within Rolling Timestamp Window
Sqlite3 (Or General SQL) Retrieve Nth Row of a Query Result
Oracle 10G Express Home Page Is Not Coming Up
Aggregate Adjacent Only Records with T-Sql
How to Pass a Parameter to a T-SQL Script
How to Connect to an External Database from a SQL Statement or a Stored Procedure