Reputation: 14364
I have a table sorted by 'category' and 'number'. I'm trying to detect the rows that don't have an increasing number. I've tried this approach:
WITH test AS (
SELECT * FROM (
VALUES
('A', 1),
('B', 2),
('C', 4),
('D', 3),
('F', 5),
('F', 6),
('G', 7),
('H', 9),
('H', 8)
) AS t(category, number)
),
test_with_previous as(
select t.*,
lag(number) over (order by category, number) as prev_number
from test t
)
select *
from test_with_previous
where prev_number > number;
Which gives:
category | number | prev_number |
---|---|---|
D | 3 | 4 |
But the first unordered row should be "C". How can I fix it?
Upvotes: 1
Views: 178
Reputation: 4048
You can add a ROW_NUMBER()
to data to get sequence number and then JOIN
with next record and filter all with increment not equal to 1, or you can simply adjust the filter to get whatever you want
;WITH
test AS (
SELECT * FROM (
VALUES
('A', 1),
('B', 2),
('C', 4),
('D', 3),
('F', 5),
('F', 6),
('G', 7),
('H', 9),
('H', 8)
) AS t(category, number)
),
test_idx as (
select *, ROW_NUMBER() over (order by category, number) id
from test
)
select t1.id, t2.id, t1.category c1, t2.category c2, t1.number n1, t2.number n2, t2.number - t1.number diff
from test_idx t1
left join test_idx t2 on t1.id = t2.id-1
where t1.number <> t2.number -1;
Outputs
id id c1 c2 n1 n2 diff
2 3 B C 2 4 2
3 4 C D 4 3 -1
4 5 D F 3 5 2
Upvotes: 1
Reputation: 19613
Use lead()
instead of lag()
:
WITH test (category, number) AS (
VALUES
('A', 1),
('B', 2),
('C', 4),
('D', 3),
('F', 5),
('F', 6),
('G', 7),
('H', 9),
('H', 8)),
test_with_next AS(
SELECT t.*, lead(number) OVER (ORDER BY category, number) AS next_number
FROM test t)
SELECT *
FROM test_with_next
WHERE next_number < number;
category | number | next_number
----------+--------+-------------
C | 4 | 3
Upvotes: 1