Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

In PostgreSQL, how can I optimize a query with which I obtain the differences between the current column and the immediately previous one?

i have this audit table

User date text text 2
u1 2023-01-01 hi yes
u1 2022-12-20 hi no
u1 2022-12-01 hello maybe

And i need as a result, something like this:

User date text text 2
u1 2023-01-01 null x
u1 2022-12-20 x x
u1 2022-12-01 null null

So i can know wich column change from the last time.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Something like this is working, but i think may be a way to optimize it? or at least generate a "more easy to look" query? (i need the information for almost 20 columns, not only 3)

SELECT 
    ta.audit_date,
    ta.audit_user,
    CASE
        WHEN ta.audit_operation = 'I' THEN 'Insert'
        WHEN ta.audit_operation = 'U' THEN 'Update'
    END AS action,
    CASE WHEN ta.column1 <> (SELECT column1
                                    FROM audit_table ta1
                                    WHERE ta1.id = 9207 AND ta1.audit_date < ta.audit_date
                                    ORDER BY ta1.audit_date DESC
                                    LIMIT 1) 
        THEN 'X' ELSE null END column1,
    CASE WHEN ta.column2 <> (SELECT column2
                                    FROM audit_table ta1
                                    WHERE ta1.id = 9207 AND ta1.audit_date < ta.audit_date
                                    ORDER BY ta1.audit_date DESC
                                    LIMIT 1) 
        THEN 'X' ELSE null END column2,
    CASE WHEN ta.column3 <> (SELECT column3
                                    FROM audit_table ta1
                                    WHERE ta1.id = 9207 AND ta1.audit_date < ta.audit_date
                                    ORDER BY ta1.audit_date DESC
                                    LIMIT 1) 
        THEN 'X' ELSE null END column3
FROM
    audit_table ta
WHERE
    ta.id = 9207
ORDER BY
    audit_date DESC

Thanks you!

>Solution :

I think you can just use the LAG() analytic function here. If I understand correctly:

SELECT *, CASE WHEN text != LAG(text) OVER (ORDER BY date) THEN 'x' END AS text_label,
          CASE WHEN text2 != LAG(text) OVER (ORDER BY date) THEN 'x' END AS text2_label
FROM yourTable
ORDER BY date; 
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading