Home > Net >  SQL subquery with comparison
SQL subquery with comparison

Time:02-01

On a Rails (5.2) app with PostgreSQL I have 2 tables: Item and ItemPrice where an item has many item_prices.

Table Item

id name
1 poetry book
2 programming book

Table ItemPrice

id item_id price
1 1 4
2 2 20
3 1 8
4 1 6
5 2 22

I am trying to select all the items for which the last price (price of the last offer price attached to it) is smaller than the one before it

So in this example, my request should only return item 1 because 6 < 8, and not item 2 because 22 > 20

I tried various combinations of Active records and SQL subqueries that would allow me to compare the last price with the second to last price but failed so far.

ex Item.all.joins(:item_prices).where('EXISTS(SELECT price FROM item_prices ORDER BY ID DESC LIMIT 1 as last_price WHERE (SELECT price FROM item_prices ... can't work it out..

CodePudding user response:

You can do it as follows using ROW_NUMBER and LAG:

LAG to get the previous row based on a condition

WITH ranked_items AS (
SELECT m.*, 
  ROW_NUMBER() OVER (PARTITION BY item_id ORDER BY id DESC) AS rn,
  LAG(price,1) OVER (PARTITION BY item_id ORDER BY id ) previous_price
  FROM ItemPrice AS m
)
SELECT it.*
FROM ranked_items itp 
inner join Item it on it.id = itp.item_id
WHERE rn = 1 and price < previous_price

Demo here

  • Related