2012-06-05 97 views
1

比方说,我有以下型号:查询在关联表的外键

Customer(customer_id (PK), firstName, lastName, email) 
Item(item_id (PK), name, description) 
Orders(orders_id (PK), customer_id (FK), item_id (FK), promotion_id (FK)), 
Promotion(promotion_id (PK), date, gift_id (FK)) 
Gift(gift_id (PK), name, description) 

现在,让我们说,我有以下要求:

检索所有订单列表(没有分组)来自所有客户以及来自物品和礼物的名称列相关联。

困难的部分是,关联表的命令有一个外键列到一个到多个表(提升),轮到他有外键的礼物; 我有工作的下面的查询,但我弄清楚,应该有一个更优雅的方式来解决这个问题不是做了很多的连接是这样的:

select concat(c.firstName, ' ', c.lastName) as customerName, 
     i.name, g.name 
from customer as c 
left join orders as o on c.customer_id = o.customer_id 
inner join item as i on o.item_id = i.item_id 
inner join promotion as p on o.promotion_id = p.promotion_id 
inner join gift as g on p.gift_id = g.gift_id; 

我怎么能解决一个更优雅的查询办法? 在此先感谢!

回答

0

我觉得这是非常优雅的。联结非常优雅,经常被误解。

0

您可以删除INNER关键字,因为默认情况下连接是内联的,而AS关键字是可选的;也因为你的列名是相同的跨越连接,你可以简单地使用USING,而不是ON

SELECT CONCAT_WS(' ', c.firstName, c.lastName) customerName, 
     i.name, g.name 
FROM customer c 
    LEFT JOIN orders o USING (customer_id) 
    JOIN item  i USING (item_id) 
    JOIN promotion p USING (promotion_id) 
    JOIN gift  g USING (gift_id) 

事实上,如果这些跨连接表具有相同名称的列只有一个可能会进一步和使用去NATURAL联接(虽然我不喜欢这样,因为它隐藏了什么事情,如果架构更改):

SELECT CONCAT_WS(' ', c.firstName, c.lastName) customerName, 
     i.name, g.name 
FROM customer   c 
    NATURAL LEFT JOIN orders o 
    NATURAL JOIN item  i 
    NATURAL JOIN promotion p 
    NATURAL JOIN gift  g 
+0

我宁愿指定INNER JOIN,而不是刚刚加入,只是为了确认这是你真正想要的东西。 –