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)

さて、次の要件があるとしましょう。

すべての顧客からのすべての注文 (グループ化されていない) のリストと、関連するアイテムとギフトの両方から名前列を取得します。

難しいのは、関連テーブルの注文には、1 対多のテーブル (プロモーション) への外部キー列があり、それがギフトへの外部キーを持つことです。次のクエリが機能しましたが、このような多くの結合を行うよりも、問題にアプローチするためのよりエレガントな方法が必要であることがわかりました。

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;

よりエレガントな方法でクエリを解決するにはどうすればよいですか? 前もって感謝します!

4

2 に答える 2

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
于 2012-06-05T03:16:44.527 に答える
0

これは完全にエレガントだと思います。Join は非常に洗練されたものであり、しばしば誤解されます。

于 2012-06-05T03:10:46.507 に答える