【问题标题】:Retrieve multiple rows from multiple tables从多个表中检索多行
【发布时间】:2017-10-30 20:54:11
【问题描述】:

我正在尝试从多个表中检索多行,但我认为我没有以正确的方式进行操作。该项目有点像网上商店,我有 3 个表:订单、订单详细信息和服务,它们都与 ID 相关联:

我在 orderdetails 的表中有订单 ID 和服务 ID,这意味着我为链接到服务 ID 的购物篮中的每个项目插入一行以查看是哪个服务,并使用订单 ID 检查哪个订单。示例:

services table
-
service_id|name   |price
------------------------
2         |Tech   |100
------------------------
4         |Support|150
------------------------
10        |Mainten|50
------------------------

orders table
-
order_id|customer_id|name|lastname
----------------------------------
10      |16         |John|Smith
----------------------------------

orderdetails table
-
orderdetails_id|order_id|service_id|price|quantity
--------------------------------------------------
1              |10      |2         |100  |4
--------------------------------------------------
2              |10      |4         |150  |2
--------------------------------------------------
3              |10      |10        |50   |1
--------------------------------------------------

我在 orderdetails 表中插入服务价格,因为可能服务价格在客户订购后会发生变化。

此时我有这个查询:

$query = $this->db->prepare(
'SELECT orders.*, orderdetails.*, services.*
FROM  orders
LEFT JOIN orderdetails
ON orderdetails.order_id = orders.order_id
LEFT JOIN services
ON orderdetails.service_id = services.service_id
WHERE orders.order_id = ?
AND orders.customer_id = ?');

我得到了这个结果:

    stdClass Object
(
    [order_id] => 10
    [customer_id] => 16
    [name] => Tech
    [lastname] => Smith
    [orderdetails_id] => 1
    [service_id] => 2
    [price] => 100
    [quantity] => 4
)
stdClass Object
(
    [order_id] => 10
    [customer_id] => 16
    [name] => Support
    [lastname] => Smith
    [orderdetails_id] => 2
    [service_id] => 4
    [price] => 150
    [quantity] => 2
)
stdClass Object
(
    [order_id] => 10
    [customer_id] => 16
    [name] => Mainten
    [lastname] => Smith
    [orderdetails_id] => 3
    [service_id] => 10
    [price] => 50
    [quantity] => 1
)

我有两个问题。第一个问题是我在订单表和服务表中有相同的列名。第二个是查询返回所有信息(因为我知道我查询的不好),但我希望收到这样的信息:

stdClass Object
(
    [order_id] => 10
    [customer_id] => 16
    [name] => John
    [lastname] => Smith
    [orderdetails_id] => 1
    [service_id] => 10
    [price] => 50
    [quantity] => 1
    [service_name] => Mainten
    [orderdetails_id2] => 2
    [service_id2] => 4
    [price2] => 150
    [quantity2] => 2
    [service_name2] => Support
    [orderdetails_id3] => 3
    [service_id3] => 2
    [price3] => 100
    [quantity3] => 4
    [service_name3] => Tech
)

我的意思是,我不是 SQL 查询方面的专家,而且我阅读了很多,但我认为你们可以帮助我弄清楚这一点,因为我还有另外两个表要链接:客户服务工作者将得到处理的订单,以及接收订单的区域表。

我使用这段代码来获取对象:

$array = array(); 
while($loop = $result->fetch_object()){ $array[] = $loop; }
return $array;

【问题讨论】:

  • 查询应该或多或少地返回你想要的,所以它似乎不是 SQL 的问题,而是 PHP 的问题。您如何从查询结果中获取该对象?您使用的代码似乎丢弃或合并重复的列名。
  • 我用这个:$array = array(); while($loop = $result->fetch_object()){ $array[] = $loop; } return $array;

标签: php mysql database-design inner-join multiple-columns


【解决方案1】:

问题是您使用fetch_object() 来获取结果,但您没有在查询中重命名具有相同名称的列,并且由于您不能有两个具有相同名称的不同对象属性,因此其余的列被丢弃。

您可以使用其他方法获取 fetch_row() 之类的值,也可以更改查询以重命名具有相同名称的列,例如:

SELECT orders.*, orderdetails_id, service_id, orderdetails.price as detail_price, quantity,
  services.name as service_name, services.price as service_price
FROM orders
LEFT JOIN orderdetails ON orderdetails.order_id = orders.order_id
LEFT JOIN services ON orderdetails.service_id = services.service_id
WHERE orders.order_id = ?


作为旁注,如果order_idorders 的主键,则您不需要在where 条件中使用customer_id,并且如果主键由两列组成(即,您可以拥有不同客户的订单ID相同)我建议更改它并仅使用order_id

【讨论】:

  • 我完全同意你的回答。这解决了第一个问题,那么第二个问题呢?我的意思是,也许我的方法是正确的,但我不确定。如果客户购买了 3 件商品,这意味着 orderdetails 表中有 3 行。客户购买的 3 件物品是否有办法接收一件物品?也许与 group_concat?这仅适用于审美问题。类似这样的话题:stackoverflow.com/questions/13451605/…
  • 对不起,我没有注意到第二个问题。关于这一点,可以将三个结果合并到同一个对象中,但这不是一个好主意,最好像现在这样拥有一个对象数组,因为只有一个对象对于相同的概念有不同的名称,所以你必须使用动态代码(这违背了将结果放入对象而不是关联数组的目的)。根据经验,当您拥有无限数量的项目时,您应该重构数据。
  • 那么,您建议使用我现在拥有的相同对象吗?这就是为什么我说“也许我的方法是正确的,但我不确定”。我不确定在每个循环中为 orderdetails 的表(谁拥有客户购买的物品)检索客户姓名和姓氏是否是一种好习惯。也许是多余的,但我不喜欢进行一次查询来获取订单,第二次查询来获取商品,第三次查询来获取客户数据,我认为这样不好。非常感谢,我会使用你的建议。
  • 是的,我建议每行使用一个对象,它有几个好处,例如在循环中使用它更容易。关于使用一个查询与多个查询,它取决于数据,如果您不“复制”很多列并且结果通常是几行,您可以保存对数据库的调用,但是如果您包含很多列每个详细结果中的主行和查询可以返回很多行,最好有单独的查询。我个人大部分时间都使用单独的查询,但有时我会包含主字段,以避免查询仅包含一/两列的行。
猜你喜欢
  • 1970-01-01
  • 2019-04-30
  • 1970-01-01
  • 1970-01-01
  • 2011-12-23
  • 2013-03-26
  • 2014-11-18
相关资源
最近更新 更多