2

看看这个数据库模式:

数据库架构

用户可以订购产品。对于任何订单,我在orders表中添加一条新记录,并在orders-products N:M 表中为用户订购的任何单个产品添加一条新记录(并填写 items 字段)。但是,当用户创建订单时,我需要显示所有产品的列表,并使用为任何产品订购的数量填写 items 字段。

通常,为此,我使用两个查询。
第一个查询获取产品表中的所有产品:

SELECT * FROM products;

第二个查询获取在orders-products表中订购的产品,通过orders-idorder FK过滤它们:

SELECT orders_idorder AS idorder, products_idproduct AS idproduct, pieces FROM orders_products WHERE orders_idorder=1;

然后我将结果合并到一个数组中,并使用它来显示完整的产品列表以及为每个产品订购的零件。最终结果是这样的:

+---------+------------+--------------+--------+---- ----+
| 订单 | 产品标识 | 描述 | 价格 | 件|
+---------+------------+--------------+--------+---- ----+
| 1 | 1 | 产品 1 | 10.20 | 2 |
| 1 | 2 | 产品 22 | 11.00 | 空 |
| 1 | 3 | 产品 333 | 19.22 | 空 |
| 1 | 4 | 产品 4444 | 9.20 | 空 |
+---------+------------+--------------+--------+---- ----+

注意:在上面的示例中,products 表中有 4 条记录,而orders-products中只有 1 条记录(idorder=1,idproduct=1 和pieces=2)。 -> 在这里你可以找到SQL Dump来测试查询。 合并从 2 个查询构建的数组是最好的方法吗?我可以用一个查询来完成吗? 你觉得演出怎么样?





4

4 回答 4

1

通常让数据库优化合并会比你在代码中做的更好。db 通常也更擅长排序。

您如何构建查询取决于您想要的结果集。如果您想要所有产品,无论它们是否出现在订单表中,那么您将使用 OUTER JOIN 否则 INNER JOIN 将过滤掉从未订购过的产品。

如果您向我们提供一些示例数据的所需结果,我们可能会帮助您进行查询,但请先自己试一试。

set @searchOrderId = 1;
select ifnull(op.orders_idorder, @searchOrderId) AS idOrder,
    p.idproduct,
    p.description,
    p.price,
    op.pieces
from products p
left join orders_products op on op.products_idproduct = p.idproduct
where ifnull(op.orders_idorder, @searchOrderId) = @searchOrderId ;

我正在玩的SQL Fiddle来测试它。

于 2013-01-15T00:59:59.143 回答
0

当然,您可以通过将表连接在一起使用单个查询来获取信息。是你遇到的问题吗?

于 2013-01-15T00:45:02.250 回答
0

我认为一般来说,执行单个查询来检索结果会比执行两个查询并合并结果更好。鉴于所提供的信息,不可能说出理想的执行计划是什么。表大小、架构等将发挥作用。

要从单个订单中检索所有产品,请尝试:

select
    o.idorder,
    p.idproduct,
    p.description,
    p.price,
    op.pieces
from
    orders o
    inner join orders_products op
        on o.idorder = op.orders_idorder
    inner join products p
        on op.products_idproduct = p.idproduct
where
    o.idorder = 1
于 2013-01-15T13:09:50.913 回答
0

我明白了,您希望将 Products 表中的 LEFT JOIN 连接到 Orders_Products。这将为您提供您正在寻找的结果。

于 2013-01-16T22:21:16.687 回答