假设我有以下型号:
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)
我觉得这很优雅。加入非常优雅,经常被误解。
答案 1 :(得分: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