子查询并为MySQL中的多个外键选择最旧的行

时间:2010-03-09 14:17:02

标签: sql mysql subquery

我有两张桌子:

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'

更新

使用子查询作为表几乎解决问题(查看答案) - 现在唯一的问题是如何从product_storage中为多个外键选择最旧的行(每个idproduct只有一个)。

更新2

感谢cmptrgeekken提供了很好的解决方案:))

5 个答案:

答案 0 :(得分: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

编辑:已更新,因为税收在另一个表格中,因此我必须移动该计算的位置。

编辑2:好的,再次改变一下,试图正确过滤product_storage表。

答案 1 :(得分: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中的所有行:/

答案 2 :(得分: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;

答案 3 :(得分: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;

答案 4 :(得分:0)

首先,您希望获得产品的最低存储ID。

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

idstorage,idproduct,添加,数量,价格 然后,您可以使用最小存储ID加入该查询和product_storage表(再次),以使用正确的定价信息获取您的产品信息。

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 (#, #, ...)