2014-07-01 96 views
1

这是我的表,它目前包含的一个小片断〜10,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每天左右的价格。

我想选择一组cardid的最近日期,当foil_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 | 
+---------+---------------------+-----------+---------------------+----------------+ 

我敢肯定,这涉及内部连接在同一个表,但我不能完全得到我的头周围。任何帮助将非常感激。

回答

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` 
    
  • +0

    感谢您的回答。纠正我,如果我错了,但不会在第一个子选择限制1防止此查询返回多个行?我需要将这些数据返回给一组卡ID,例如, card_id in(10000,20000,...) – lebenski

    +0

    好像我误解了你的问题 - 我以为你只想得到最后一个值,覆盖所有行。我会编辑我的答案。 –

    +0

    完成,回答编辑。 –

    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 ; 
    

    OR

    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; 
    
    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

    0

    怎么样,如果你有2000万行......

    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 | 
    +---------+---------------------+----------------+-------------+ 
    
    相关问题