Search code examples
mysqlsqlcorrelated-subquery

mysql correlated subquery : select field1 where max(field2)


What is the most efficient way to select the time where price has increased the max? [Structure at the bottom]

-- get max increased price

select p1.pricetime, max(p2.price) maxnext
from prices p1 inner join prices p2 on p2.id > p1.id
group by p1.pricetime

what is p2.pricetime where p2.price = max(p2.price) for each p1.pricetime?

-- get time of max price

select p3.pricetime, x.maxnext
from prices p3 inner join 

(select p1.pricetime, max(p2.price) maxnext
from prices p1 inner join prices p2 on p2.id > p1.id
group by p1.pricetime) x

on x.maxnext = p3.price and p3.id > p1.id

that is a horribly inefficient way for multi million row tables I'm sure you could do something like this in MSSQL :

select p2.pricetime from 
(select p1.pricetime, max(p2.price) maxnext
from prices p1 inner join prices p2 on p2.id > p1.id
group by p1.pricetime) x ...

which accesses a subquery alias from outside the subquery?

-- structure :

CREATE TABLE `prices` (
  `id` int(11) NOT NULL DEFAULT '0',
  `pricetime` varchar(19) DEFAULT NULL,
  `price` decimal(10,8) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

LOCK TABLES `prices` WRITE;
/*!40000 ALTER TABLE `prices` DISABLE KEYS */;

INSERT INTO `prices` (`id`, `pricetime`, `price`)
VALUES
    (1,'2014-01-01 21:55:00',1.37622000),
    (2,'2014-01-01 21:56:00',1.37616000),
    (3,'2014-01-01 21:57:00',1.37616000),
    (4,'2014-01-01 21:58:00',1.37498000),
    (5,'2014-01-01 21:59:00',1.37529000),
    (6,'2014-01-01 22:03:00',1.37518000),
    (7,'2014-01-01 22:05:00',1.37542000),
    (8,'2014-01-01 22:06:00',1.37558000),
    (9,'2014-01-01 22:07:00',1.37560000),
    (10,'2014-01-01 22:08:00',1.37560000);

/*!40000 ALTER TABLE `prices` ENABLE KEYS */;
UNLOCK TABLES;

Solution

  • Thanks Gordon, when I asked the question stackoverflow suggested correlated-subquery as a tag. Therein lied the answer. So here goes :

    The time of maximum increase :

    SELECT p1.pricetime starttime, min(p4.pricetime) endtime, 
    p1.price startingprice, p4.price maxnextprice
    FROM prices p1 inner join prices p4 on p4.id > p1.id
    WHERE p4.price = 
    (SELECT max(p3.price) 
    FROM prices p2 inner join prices p3 on p3.id > p2.id 
    where p1.id = p2.id 
    group by p2.pricetime order by max(p3.price) limit 1)
    group by p1.pricetime, p4.price;
    

    Thanks for your input.