对于不同的条件,从同一个表中选择两次max(date)

时间:2014-07-01 12:05:47

标签: mysql sql select join inner-join

这是我的表格的一小部分,目前包含~100,000,000行

+---------+---------------------+-----------+----------------+
| card_id | date                | avg_price | foil_avg_price |
+---------+---------------------+-----------+----------------+
|   10000 | 2014-06-28 09:05:56 |      5.02 |          10.22 |
|   20000 | 2014-06-28 09:05:54 |     14.58 |          25.10 |
|   10000 | 2014-06-29 09:05:56 |      0.00 |          19.62 |
|   20000 | 2014-06-29 09:05:54 |     14.58 |          0.00  |
|   10000 | 2014-07-01 09:05:56 |      0.00 |          19.62 |
|   20000 | 2014-07-01 09:05:54 |      0.00 |          25.10 |
+---------+---------------------+-----------+----------------+

这是卡片的价格历史,包括avg_price以及每天左右的foil_avg_price的内容。

我想选择一组卡片ID,这是箔片_avg_price为>的最新日期。 0,该价格是什么,以及avg_price最近的日期> 0,那个价格是多少。我上面得到的数据集看起来像这样:

+---------+---------------------+-----------+---------------------+----------------+
| card_id | avg_date            | avg_price | foil_date           | foil_avg_price |
+---------+---------------------+-----------+---------------------+----------------+
|   10000 | 2014-06-28 09:05:56 |      5.02 | 2014-07-01 09:05:54 |          19.62 |
|   20000 | 2014-06-29 09:05:54 |     14.58 | 2014-07-01 09:05:54 |          25.10 |
+---------+---------------------+-----------+---------------------+----------------+

我确信这涉及到同一张桌子上的INNER JOIN,但我无法理解它。任何帮助将不胜感激。

4 个答案:

答案 0 :(得分:1)

三个步骤:

  • 查找上次价格日期
  • 查找上次贴膜价格日期
  • 解决这些日期的价格

所以,

SELECT dates.*, price.avg_price, foilprice.foil_avg_price 
FROM (
    SELECT 
      card_id,
      MAX(IF(avg_price>0, `date`, '0001-01-01')) AS avg_date,
      MAX(IF(foil_avg_price>0, `date`, '0001-01-01')) AS foil_avg_date
    FROM card_price
    GROUP BY card_id
  ) AS dates
  INNER JOIN card_price AS price
    ON dates.card_id=price.`date`
  INNER JOIN card_price AS foilprice
    ON dates.card_id=foilprice.`date`

答案 1 :(得分:0)

试试这个:

SELECT a.card_id, a.avg_date, a.avg_price, b.foil_date, b.foil_avg_price
FROM (SELECT c.card_id, c.date AS avg_date, c.avg_price  
      FROM cards c 
      INNER JOIN (SELECT c.card_id, MAX(IF(c.avg_price > 0, c.date, NULL)) avg_date 
                  FROM cards c GROUP BY c.card_id
                ) a ON c.card_id = a.card_id AND c.date = a.avg_date 
     ) AS a
LEFT JOIN (SELECT c.card_id, c.date AS foil_date, c.foil_avg_price  
           FROM cards c 
           INNER JOIN (SELECT c.card_id, MAX(IF(c.foil_avg_price > 0, c.date, NULL)) foil_date 
                       FROM cards c GROUP BY c.card_id
                     ) a ON c.card_id = a.card_id AND c.date = a.foil_date
         ) AS b ON a.card_id = b.card_id ;

SELECT a.card_id, a.avg_date, a.avg_price, b.foil_date, b.foil_avg_price
FROM (SELECT * 
      FROM (SELECT c.card_id, c.date, c.avg_price 
            FROM cards c WHERE c.avg_price > 0 
            ORDER BY c.date DESC
          ) AS A 
      GROUP BY A.date
     ) AS a 
LEFT JOIN ( SELECT * 
            FROM (SELECT c.card_id, c.date, c.foil_avg_price 
                  FROM cards c WHERE c.foil_avg_price > 0 
                  ORDER BY c.date DESC
                ) AS B 
            GROUP BY B.date
          ) AS b ON a.card_id = b.card_id;

答案 2 :(得分:0)

尝试此查询

SELECT A.card_id,max(date),MAX(avg_price), (SELECT MAX(date) FROM test WHERE card_id = A.card_id AND foil_avg_price = MAX(A.foil_avg_price)) AS date,MAX(foil_avg_price) FROM test A

GROUP BY A.card_id

答案 3 :(得分:0)

如果你有20,000,000行......

DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table
(card_id INT NOT NULL
,date DATETIME NOT NULL               
,price_type VARCHAR(20) NOT NULL
,price_value DECIMAL(5,2) NOT NULL
,PRIMARY KEY(card_id,date,price_type)
);

INSERT INTO my_table VALUES
(10000,'2014-06-28 09:05:56','avg_price',5.02),
(20000,'2014-06-28 09:05:54','avg_price',14.58),
(10000,'2014-06-29 09:05:56','avg_price',0.00),
(20000,'2014-06-29 09:05:54','avg_price',14.58),
(10000,'2014-07-01 09:05:56','avg_price',0.00),
(20000,'2014-07-01 09:05:54','avg_price',0.00),
(10000,'2014-06-28 09:05:56','foil_avg_price',10.22),
(20000,'2014-06-28 09:05:54','foil_avg_price',25.10),
(10000,'2014-06-29 09:05:56','foil_avg_price',19.62),
(20000,'2014-06-29 09:05:54','foil_avg_price',0.00),
(10000,'2014-07-01 09:05:56','foil_avg_price',19.62),
(20000,'2014-07-01 09:05:54','foil_avg_price',25.10);

SELECT x.* 
  FROM my_table x
  JOIN 
     ( SELECT card_id,price_type,MAX(date) max_date FROM my_table WHERE price_value > 0 GROUP BY card_id,price_type) y
    ON y.card_id = x.card_id 
   AND y.price_type = x.price_type 
   AND y.max_date = x.date;
+---------+---------------------+----------------+-------------+
| card_id | date                | price_type     | price_value |
+---------+---------------------+----------------+-------------+
|   10000 | 2014-06-28 09:05:56 | avg_price      |        5.02 |
|   10000 | 2014-07-01 09:05:56 | foil_avg_price |       19.62 |
|   20000 | 2014-06-29 09:05:54 | avg_price      |       14.58 |
|   20000 | 2014-07-01 09:05:54 | foil_avg_price |       25.10 |
+---------+---------------------+----------------+-------------+