【问题标题】:Find all rows that has a changed column value over time in SQL [closed]Find all rows that has a changed column value over time in SQL [closed]
【发布时间】:2022-12-27 00:41:43
【问题描述】:

So I have three columns: Time_id, accounts and code. See attached picture for a sn-p of the data.

I want to find all account that have changed the code from 7100 to 7000 for that account, with ordered by the most recent ones.

  • Time_id: is the date generated once every month for each account with updated fields. In the format of yyyymmdd
  • account: is an unique account id for this customer
  • code: is a four letter digit describing

I have tried a LAG of 'code' over a partition by time_id. However this returned a LAG code of from a different account. Not sure how to transform the query to only return changed code from LAG based on the same accounts. This was the query I tried:

SELECT time_id, account, code
    ,LAG(code, 1) OVER (partition by time_id order by time_id) LAG_1
  FROM my_table
  group by time_id, account, code

I was hoping to get all the accounts and the rows where code went from 7100 to 7000 and when it happened. For instance I want to get account 12500 and 15500 returned from the table below with the row when it changed from 7100:

time_id account code
20220510 12500 7100
20221101 12500 7000
20221120 12500 7000
20221201 17500 7100
20221202 12500 7100
20221203 15500 7100
20221204 15500 7000
20221205 15500 7000

I appreciate any new suggestions. Or improvements to my own query

【问题讨论】:

  • Please provide proper sample data and the desired results and the table schema.
  • We don't know for sure what it changed FROM here but consider WHERE code = 7000 - for example your last three rows in the last block looks like it changed from 7000 to 7000 SO do you want the first row that is 7000 or the last one since it did not appear to change..
  • @stu just curious: how much more sample data do I need to provide? I added desired result in the text based on sample data in the table. How is table schema necessary to get help on this exact table? I want to be more clear on my questions in the future. If you feel this was insufficient for people to help me please point out exactly what and why I should make certain changes to it. Thank you!

标签: sql sql-server lag


【解决方案1】:

Recall that PARTITION BY is the rolling window equivalent of a GROUP BY. Since you want to look at the changes in codefor a particular account, you need to partition by account:

    SELECT
        time_id,
        account,
        code,
        LAG(code) OVER (
          PARTITION BY account
          ORDER BY time_id
        ) AS previous_code
      FROM
        my_table

This query will return your original (time_id, account, code) records with a new column, previous_code, which denotes the value of code for the most recent preceding record for that account.

Now we can make progress:

WITH lagged_table AS (
    SELECT
        time_id,
        account,
        code,
        LAG(code) OVER (
          PARTITION BY account
          ORDER BY time_id
        ) AS previous_code
      FROM
        my_table
)

    SELECT
        time_id,
        account
      FROM
        lagged_table
     WHERE
           previous_code = 7100
       AND code = 7000

This should get you exactly what you want: an account ID and a time for all cases when the code switched from 7100 to 7000.

【讨论】:

  • Thank you @Paddy! Clear and concise answer, and feedback on where I went wrong.
猜你喜欢
  • 2022-12-27
  • 2022-12-19
  • 2022-10-25
  • 2022-12-02
  • 2022-12-02
  • 2012-09-19
  • 1970-01-01
  • 2022-12-01
  • 2022-12-02
相关资源
最近更新 更多