0

I have following table:

day              cat    x1    x2
2019-10-25       A      P     Open
2019-10-26       A      P     Close
2019-10-27       A      P     Close
2019-10-28       A      I     Close
2019-10-26       B      P     Close
2019-10-27       B      P     Open
2019-10-28       B      P     Open

How can I get rows where either "x1" or "x2" has changed within a category "cat"?

day              cat    x1    x2
2019-10-26       A      P     Close
2019-10-28       A      I     Close
2019-10-27       B      P     Open

I have found some questions with one column changed, but struggling a bit with categorized table and capturing changes from two columns

4
  • what is the version of SQL Server you are using ? Commented Oct 30, 2019 at 11:57
  • SQL Server version - v18.1 Commented Oct 30, 2019 at 12:03
  • that is the version of the SQL Server Management Studio. Not the SQL Server. Do a print @@version to see Commented Oct 30, 2019 at 12:05
  • Oh sorry, Microsoft SQL Azure (RTM) - 12.0.2000.8 Commented Oct 30, 2019 at 12:15

2 Answers 2

2

you can use the window function lag() on column x1 and x2 and compare. What you want is a OR condition

select  *
from
(
    select  *,
            prev_x1 = lag(x1) over(partition by [cat] order by [day]),
            prev_x2 = lag(x2) over(partition by [cat] order by [day])
    from    your_table t
) d
where   x1  <> prev_x1
or      x2  <> prev_x2
Sign up to request clarification or add additional context in comments.

Comments

1

If you don't have the LAG function, you can use a ROW_NUMBER() to generate a ranking of categories by day, then INNER JOIN against previous record.

;WITH RowNumberByCategory AS
(
    SELECT
        T.day,
        T.cat,
        T.x1,
        T.x2,
        RowNumberByCategory = ROW_NUMBER() OVER (PARTITION BY T.cat ORDER BY T.day ASC)
    FROM
        YourTable AS T
)
SELECT
    T.*
FROM
    RowNumberByCategory AS T
    INNER JOIN RowNumberByCategory AS N ON
        T.cat = N.cat AND
        T.RowNumberByCategory - 1 = N.RowNumberByCategory
WHERE
    T.x1 <> N.x1 OR T.x2 <> N.x2

Make sure to check against NULL values with ISNULL on the WHERE if your x1 or x2 columns can be NULL.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.