2014-07-01 5 views
1

Это небольшой фрагмент из моей таблицы, которая в настоящее время содержит ~ 10000000 строкВыбор макс (дата) дважды из одной и той же таблицы, для различных условий

+---------+---------------------+-----------+----------------+ 
| 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 было на каждый день или около того.

Я хотел бы выбрать для группы идентификаторов карты самую последнюю дату, когда 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

Спасибо за ответ. Исправьте меня, если я ошибаюсь, но не будет ли LIMIT 1 в первом подборе, чтобы этот запрос не возвращал больше одной строки? Мне нужно вернуть эти данные для группы идентификаторов карт, например. 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 ; 

ИЛИ

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

Как насчет, если у вас 20000000 строк ...

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 | 
+---------+---------------------+----------------+-------------+ 
Смежные вопросы