2010-03-09 1 views
4

У меня есть две таблицы:подзапросов и выбор старых строк для нескольких внешних ключей в MySQL

product (idproduct, name, description, tax) 

product_storage (idstorage, idproduct, added, quantity, price) 

для каждого продукта она может отличаться ценой и старейшая являются «первым, чтобы продавать»

, например, в памяти у меня есть:

1, 1, 2010-01-01, 0, 10.0 
2, 1, 2010-01-02, 0, 11.0 
3, 1, 2010-01-03, 10, 12.0 
4, 2, 2010-01-04, 0, 12.0 
5, 2, 2010-01-05, 10, 11.0 
6, 2, 2010-01-06, 10, 13.0 
7, 3, 2010-01-07, 10, 14.0 
8, 3, 2010-01-08, 10, 16.0 
9, 3, 2010-01-09, 10, 13.0 

и теперь мне нужно, чтобы выбрать все продукты с текущей ценой, которая находится в самой старой строке в product_storage, где количество> 0 для каждого продукта:

SELECT p.idproduct, p.name, p.tax, 
     (SELECT s.price 
     FROM product_storage s 
     WHERE s.idproduct=p.idproduct AND s.quantity > 0 
     ORDER BY s.added ASC 
     LIMIT 1) AS price 
FROM product p; 

работает нормально, но это не делает, когда я хочу, чтобы рассчитать цену с налогом в запросе:

SELECT p.idproduct, p.name, p.tax, 
     (SELECT s.price 
     FROM product_storage s 
     WHERE s.idproduct=p.idproduct AND s.quantity > 0 
     ORDER BY s.added ASC 
     LIMIT 1) AS price, 
     (price * (1 + tax/100)) AS price_with_tax 
FROM product p; 

MySQL говорит:

Unknown column 'price' in 'field list' 

Update

Использование Подзапрос как таблица почти решает проблему (см. ответы) - вопрос только в том, как выбрать самые старые строки из product_storage для нескольких внешних ключей (один и только один для каждого idproduct).

Update 2

Благодаря cmptrgeekken для отличного решения :))

ответ

1

Причина, по которой вы получаете ошибку price doesn't exist, заключается в том, что вы не можете ссылаться на столбцы с псевдонимом в списке столбцов. Чтобы это исправить, сохранить значение price в определенной пользователем переменной и ссылки, которые, например, так:

SELECT p.idproduct, p.name, p.tax, 
     @price := (SELECT s.price 
     FROM product_storage s 
     WHERE s.idproduct=p.idproduct AND s.quantity > 0 
     ORDER BY s.added ASC 
     LIMIT 1) AS price, 
     (@price * (1 + tax/100)) AS price_with_tax 
FROM product p; 
+0

превосходно - спасибо много :) – Marek

1

это работает почти нормально:

SELECT p.idproduct, p.name, p.tax, 
     sub.price, (sub.price * (1+tax/100)) as price_with_tax 
FROM product p, 
    (SELECT s.idproduct, s.price 
    FROM product_storage s 
    WHERE quantity > 0 
    ORDER BY added ASC) sub 
WHERE p.idproduct=sub.idproduct 

, но все строки из product_storage возвращаются для каждого продукта:/

0

Что касается MySQL, то последнее вхождение слова «цена» относится к полю в Продукт p, следовательно, ошибка. Вам необходимо снова обратиться к совмещенному подзапросу прямо над что:

SELECT p.idproduct, p.name, p.tax, 
     (SELECT s.price 
     FROM product_storage s 
     WHERE s.idproduct=p.idproduct AND s.quantity > 0 
     ORDER BY s.added ASC 
     LIMIT 1) AS price, 
     (  (SELECT s.price 
     FROM product_storage s 
     WHERE s.idproduct=p.idproduct AND s.quantity > 0 
     ORDER BY s.added ASC 
     LIMIT 1) * (1 + tax/100)) AS price_with_tax 
FROM product p; 
+0

В таблице «продукт» нет поля «цена» - вы уверены, что этот повторный подзапрос не рассчитан снова? – Marek

+0

Это было то, что я не смог прояснить в своем посте. Вы не можете использовать свое поле псевдонимов для вычисления налогового значения, потому что MySQL ищет столбец «цена» в таблице «Продукт». Итак, я написал явно запрошенное значение из Product_Storage снова. Во всяком случае, я думаю, что ответ PowerLord в целом лучше (см. Рисунок). – LesterDove

2

Это может работать лучше, используя подзапрос в виде таблицы:

SELECT p.idproduct, p.name, p.tax, s.price, (s.price * (1 + p.tax/100)) as price_with_tax 
FROM product p 
INNER JOIN (SELECT idproduct, price 
     FROM product_storage 
     WHERE quantity > 0) s 
ON p.idproduct = s.idproduct 
INNER JOIN (SELECT idproduct, MIN(added) min 
     FROM product_storage 
     GROUP BY idproduct) f 
ON s.idproduct = f.idproduct AND s.added = f.min 

Edit: Обновленная потому налог в другой таблице, так Мне пришлось переместить местоположение этого расчета.

Редактировать 2: ОК, все изменилось, чтобы попытаться правильно фильтровать таблицу product_storage.

+0

«Неизвестный столб« налог »в« списке полей » – Marek

+0

Возможно, мне нужно денормализовать таблицы и повторить налоговые данные в product_storage? – Marek

+0

@Marek: О, крики, налог в другом столе, не так ли. – Powerlord

0

Во-первых, вы хотите, чтобы получить самый низкий идентификатор для хранения продукта (ов).

SELECT idproduct, MIN(idstorage) idstorage FROM product_storage 
WHERE quantity>0 AND idproduct IN (#, #, ...) 
GROUP BY idstorage 

idstorage, idproduct, добавлено, количество, цена Затем вы можете присоединиться на этот запрос и product_storage таблицы (снова), используя мин для хранения ID, чтобы получить информацию о продукте с правильной информацией ценообразовании.

SELECT idproduct, name, description, tax, ps.price, ps.quantity, 
FROM product AS p 
JOIN 
(SELECT idproduct, MIN(idstorage) idstorage FROM product_storage 
WHERE quantity>0 AND idproduct IN (#, #, ...) 
GROUP BY idstorage) AS min_id 
ON p.idproduct=min_id.idproduct 
RIGHT JOIN product_storage AS ps ON ps.idstorage=min_id.idstorage 
WHERE idproduct IN (#, #, ...) 
+0

«... idproduct IN (#, #, ...) ..." - idproduct не указан - например, я беру новейшие продукты, продукты из категории X и т. Д. – Marek

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