Miles Collier
Miles Collier

Reputation: 370

Finding the largest price increase/decrease in a MySQL table

I am trying to find a way to get the largest price difference (in a time frame, e.g. 24 hours) in a MySQL table using a source and productId as reference.

Here is a sample product, productId 22.

id  price  createdAt           updatedAt           sourceId productId
21  799.00 2017-07-26 19:46:46 2017-07-26 19:46:45 1        22
853 920.00 2017-07-26 06:46:46 2017-07-26 06:46:46 1        22
855 799.00 2017-07-22 16:17:11 2017-07-22 16:17:11 2        22
851 770.00 2017-07-21 16:17:11 2017-07-21 16:17:11 1        22
856 799.00 2017-07-20 16:17:11 2017-07-20 16:17:11 2        22
852 599.00 2017-07-19 16:17:11 2017-07-19 16:17:11 1        22
857 810.00 2017-07-18 16:17:11 2017-07-18 16:17:11 2        22
858 799.00 2017-07-17 16:17:11 2017-07-17 16:17:11 2        22

In the example above for productId 22 I am sorting by createdAt, so in this scenario I'd take id 21 and substract it from id 853, this would give -121, meaning the product went down 121 dollars.

In the full data it's a mush up of prices, sourceIds and productIds. The goal here is to make a result look like this:

id  createdAt            sourceId productId adjustment
21  2017-07-26 19:46:46  1        22        -121
22  2017-07-26 16:46:46  2        22        201
23  2017-07-26 15:46:46  6        24        -20

Above is kind of how I am trying to get the data to look, so I'll know of the price difference of each product of each source. Then I can control the data, such as ordering by adjustment and seeing which source + product had the largest decrease or increase in a time frame.

I've tried doing a ton of sub-queries, I've probably put in a hundred examples that I've modified from Google. I can piece together parts of this, such as only getting products that have recieved a change of any kind from the past 24 hours. I've tried to merge the last two rows of each product Id, then do a math, and list all the products. It's been 2 days of trying to build this query, is it just best for me to not use queries for everything and do it on my backend?

I've even went to a support site like hackhands and they couldn't figure it out. I've exhausted all of my ideas.

Upvotes: 0

Views: 110

Answers (1)

Juan
Juan

Reputation: 5589

This query breaks down the problem:

1) Getting the records corresponding to start_at time of the window for each product in order to get the baseline price.

2) Gets the the records for the max price for each product in the time frame.

3) Gets the records for the min price for each product in the time frame.

4) Combines 1 and 2 and 3 to form a single record per product and shows the info and the difference between base line price and the highest and lowest in the time frame.

If you only need the bigger of the two you can add and extra layer of select wrapping this query and user GREATER(a,b) to keep one diff or the other.

select BOWPRICE.product_id, BOWPRICE.created_at, BOWPRICE.price, 
MAXPRICE.max_price_upd_time,  MAXPRICE.max_price, ABS((BOWPRICE.price - MAXPRICE.max_price)) max_price_diff,
MINPRICE.min_price_upd_time,  MINPRICE.min_price, ABS((BOWPRICE.price - MINPRICE.min_price)) min_price_diff
 from  
(
    select mainA.product_id, mainA.created_at, mainA.price from SOTEST mainA 
    where id in ( 
      select id
      from SOTEST N 
      where created_at = (
          select min(N1.created_at) 
          from SOTEST N1
          where N1.created_at >= '2017-07-26 00:00:00'
          and N1.product_id = N.product_id 
      ) 
      group by mainT.product_id 
    )
) BOWPRICE,
(
  select mainB.product_id, mainB.updated_at max_price_upd_time, mainB.price max_price from SOTEST mainB
  where id in(
    select id from SOTEST M
    where M.price = (
      select max(M1.price) 
      from SOTEST M1
      where M1.created_at >= '2017-07-26 00:00:00'
      and M1.created_at < '2017-07-27 00:00:00'
      and M1.product_id = M.product_id 
      group by product_id LIMIT 1
    ) 
  )
) MAXPRICE,
(
  select mainC.product_id, mainC.updated_at min_price_upd_time, mainC.price min_price from SOTEST mainC
  where id in(
    select id from SOTEST Q
    where Q.price = (
      select min(Q1.price) 
      from SOTEST Q1
      where Q1.created_at >= '2017-07-26 00:00:00'
      and Q1.created_at < '2017-07-27 00:00:00'
      and Q1.product_id = Q.product_id 
      group by product_id LIMIT 1
    ) 
  )
) MINPRICE
where BOWPRICE.product_id = MAXPRICE.product_id
and BOWPRICE.product_id = MINPRICE.product_id

Upvotes: 2

Related Questions