2015-06-17 2 views
-1

У меня есть список продуктов и список категорий.
Каждый товар относится к некоторым категориям в определенное время,
i.e время от времени мы меняем товары в категориях.
Получить список продуктов данной категории на основе последнего моментального снимка?

Таким образом, чтобы сохранить журнал, у меня есть таблица Product_Category с 3-мя полями:

category_id [INT], product_id [INT], snapshot_date [DATE] 

Где snapshot_date это последнее время обновления категории со всеми продуктами

Я хочу, чтобы выбрать все продукты ids, для данной категории_ид (предположим, category_id = 1), где я хочу только товары для последнего моментального снимка этой категории

Например, предположим данные в Product_Category:

+-------------+------------+---------------+ 
| category_id | product_id | snapshot_date | 
+-------------+------------+---------------+ 
|  1  |  1  | 2015-01-01 | -----> old snapshot ignore it 
|  1  |  2  | 2015-01-01 | -----> old snapshot ignore it 
|  1  |  3  | 2015-01-01 | -----> old snapshot ignore it 
|  1  |  1  | 2015-01-07 | -----> last snapshot for category 1, this is my target 
|  1  |  5  | 2015-01-07 | -----> last snapshot for category 1, this is my target 
|  1  |  7  | 2015-01-07 | -----> last snapshot for category 1, this is my target 
|  2  |  5  | 2015-01-01 | -----> another category, old snapshot, ignore it 
|  2  |  7  | 2015-01-07 | -----> another category, last snapshot, ignore it 
|  2  |  3  | 2015-01-07 | -----> another category, last snapshot, ignore it 
+-------------+------------+---------------+ 

Учитывая category_id = 1, я хочу, чтобы результат

+------------+ 
| product_id | 
+------------+ 
|  1  | 
|  5  | 
|  7  | 
+------------+ 

Вот что я сделал до сих пор:

SELECT product_id 
FROM Product_Category 
WHERE category_id = 1 
     AND snapshot_date = (
      SELECT MAX(snapshot_date) 
      FROM Product_Category 
      WHERE category_id = 1 
    ); 

Есть ли лучшее решение тха делать вложенными выбирает?
PS, я использую MySQL, если ответ может быть различным на основе РСУБД

+0

Yup, один продукт может существовать в нескольких категориях, например, продукт «treadmill» находится в категории «фитнес-устройства» и категории «электронные устройства», он предназначен для упрощенных открытых данных –

+0

. , Я понял. Ваш запрос в порядке. –

+0

Не входит ли вложенный выбор очень плохой в производительности? O (n^2)? Вот почему я ищу альтернативу –

ответ

1

Ваш запрос должен быть точным. Однако некоторые версии MySQL могут запускать подзапрос для каждой строки, обработанной во внешнем запросе. Решение, что является перемещение подзапрос в предложении FROM:

SELECT pc.product_id 
FROM Product_Category pc JOIN 
    (SELECT category_id, MAX(snapshot_date) as maxsd 
     FROM Product_Category 
     WHERE category_id = 1 
     GROUP BY category_id 
    ) pcmax 
    ON pc.category_id = pcmax.category_id and 
     pc.snapshot_date = pcmax.stampshot_date; 

Большинство баз данных (в том числе и я считаю, что более поздние версии MySQL) будет выполнять только подзапрос один раз в запросе. Однако эта структура гарантирует, что подзапрос выполняется только один раз.

Смежные вопросы