Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MYSQL query - get rows where price is changed

Tags:

mysql

I have two tables viz. order and orderitem. Order table contains date and orderitem table has quantity and price for that order. I want to find the dates where the price has been changed. for example today the price is 10 and after 2 days it become 11 and then remain 11 for next 5 days then again it becomes 10 after 5 days so the result would be 3 dates 10, 11, 10 and the date would be when the price changed

        Date                     price

        '2015-04-29 14:48:23',  15.99
        '2015-04-30 14:20:11',  15.99
        '2015-04-30 21:05:11',  15.99
        '2015-05-04 01:41:12',  15.99
        '2015-07-28 05:52:20',  15.99
        '2015-07-29 16:55:48',  15.99
        '2015-08-01 00:31:53',  15.99
        '2015-08-15 22:41:49',  15.99
        '2015-08-17 02:37:43',  15.99
        '2015-08-17 13:28:03',  15.99
        '2015-08-23 04:16:31',  15.99   
        '2015-08-27 08:43:48',  15.99
        '2015-08-28 18:42:27',  15.99
        '2015-08-29 15:47:17',  15.99
        '2015-08-30 03:33:15',  15.99
        '2015-10-29 03:45:25',  15.99
        '2015-10-29 18:24:20',  15.99
        '2015-10-30 18:17:18',  15.99
        '2015-11-02 15:28:16',  16.99
        '2015-11-03 01:59:03',  16.99
        '2015-11-14 18:22:39',  16.99
        '2015-11-20 02:48:59',  16.99
        '2015-12-16 18:59:54',  16.99
        '2015-12-28 04:08:22',  16.99
        '2016-01-12 03:21:35',  16.99
        '2016-01-18 00:43:56',  16.99
        '2016-01-18 20:11:23',  16.99
        '2016-02-10 19:07:57',  16.99
        '2016-02-26 14:24:29',  16.99
        '2016-03-28 10:17:24',  16.99
        '2016-03-31 23:33:53',  16.99
        '2016-04-01 20:03:03',  17.99
        '2016-05-31 20:30:50',  15.99

I want to get all those date where the price has been changed. Here the output would be

        '2015-04-29 14:48:23',  15.99
        '2015-11-02 15:28:16',  16.99
        '2016-04-01 20:03:03',  17.99
        '2016-05-31 20:30:50',  15.99

i.e. show dates when the price has been changed.

I have written this MYSQL query so far but it gives all rows and does not filter the results:

         SELECT date, price FROM orderitem
         inner join orders o1 on o1.orderid = orderitem.orderid
         where productname = 'IBC'
        and price <> (
        select price from orderitem
        inner join orders on orders.orderid = orderitem.orderid
        where orders.date< o1.date
        order by date desc
        limit 1
        )

Any advise would be appreciated.

like image 394
user1254053 Avatar asked Dec 06 '25 21:12

user1254053


1 Answers

For something like this, you need two passes, because you will be comparing each row to the one before it.

One such way of doing this would be to first:

SET @lastprice = 0.0;

Then, your "first pass" will look like:

SELECT `Date`, @lastprice AS `oldprice`, @lastprice := `price` AS `newprice`
FROM `tablename` ORDER BY `Date` ASC;

The order is important here, as you want to build a chronological timeline.

Then, all you need to do is retrieve the rows from this result where the old and new prices are different. Something like this will do:

SELECT * FROM ("Above subquery here") `tmp` WHERE `oldprice` != `newprice`;

Your final query would look something like this:

SET @lastprice = 0.0;
SELECT * FROM (
    SELECT `Date`, @lastprice AS `oldprice`, @lastprice := `price` AS `newprice`
    FORM `tablename` ORDER BY `Date` ASC
) `tmp`
WHERE `oldprice` != `newprice`;

Alternatively, you may prefer to use a temporary table to store the subquery results. In that case, it would look something like this:

SET @lastprice = 0.0;
CREATE TEMPORARY TABLE `tmp`
    SELECT `Date`, @lastprice AS `oldprice`, @lastprice := `price` AS `newprice`
    FROM `tablename` ORDER BY `Date` ASC;
SELECT * FROM `tmp` WHERE `oldprice` != `newprice`;
DROP TEMPORARY TABLE `tmp`;

The exact implementation is up to you, but this would be a good way to do it.

like image 183
Niet the Dark Absol Avatar answered Dec 09 '25 14:12

Niet the Dark Absol