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

发布于 2024-08-24 09:42:53 字数 1397 浏览 5 评论 0原文

我有两个表:

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 提供了很好的解决方案:))

I have two tables:

product (idproduct, name, description, tax)

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

for each product it could be different price and oldest are "first-to-sell"

for example in storage I have:

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

and now I need to select all products with current price, which is in the oldest row in product_storage where quantity > 0 for each product:

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;

works fine, but it doesn't when I want to calculate price with tax in query:

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 says:

Unknown column 'price' in 'field list'

Update

Using subquery as a table almost solves problem (look at answers) - the only question now is how to select oldest rows from product_storage for multiple foreign keys (one and only one for each idproduct).

Update 2

Thanks to cmptrgeekken for great solution :))

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

花间憩 2024-08-31 09:42:54

使用子查询作为表可能会更好:

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表。

This might work better using the subquery as a table:

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: Updated because tax is in the other table, so I had to move that calculation's location.

Edit 2: OK, changed things around again to try to filter the product_storage table properly.

热风软妹 2024-08-31 09:42:54

您收到价格不存在错误的原因是您无法引用列列表中的别名列。要解决此问题,请将 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;

The reason you're getting the price doesn't exist error is because you can't reference aliased columns in the column list. To fix this, store the price value in a user-defined variable and reference that, like so:

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;
无妨# 2024-08-31 09:42:54

这几乎可以正常工作:

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中的所有行:/

this works almost fine:

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

but all rows from product_storage are returned for each product :/

泡沫很甜 2024-08-31 09:42:54

就 MySQL 而言,最后一次出现的单词“price”指的是 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,
        (       (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;

As far as MySQL is concerned, that last occurrence of the word "price" is referring to a field in Product p, hence the error. You need to refer again to the aliased subquery right above that:

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;
挽清梦 2024-08-31 09:42:54

首先,您想要获取产品的最低存储 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 (#, #, ...)

First, you want to get the lowest storage id for the product(s).

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

idstorage, idproduct, added, quantity, price
Then you can join on that query and the product_storage table (again), using the min storage ID, to get your product info with the correct pricing info.

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 (#, #, ...)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文