有没有更好的方法来使用表a或表b中的值?

时间:2013-04-12 08:18:51

标签: mysql left-join

我有三个表:ordersuser_addressesalternate_addresses。用户始终具有user_address。订单包含alternate_address_id,其中可能包含alternate_address_idNULL

现在我的查询看起来像这样:

SELECT
  IF(ISNULL(orders.alternate_address_id), a.firstname, u.firstname) AS firstname,
  IF(ISNULL(orders.alternate_address_id), a.lastname, u.lastname) AS lastname
  -- etc.
FROM orders
LEFT JOIN alternate_addresses a ON (
  orders.alternate_address_id IS NOT NULL
  AND orders.alternate_address_id = a.alternate_address_id)
LEFT JOIN user_addresses u ON (
  orders.alternate_address_id IS NULL
  AND orders.user_id = u.user_id)

对于每个地址字段执行IF(ISNULL())部分似乎有点多余,因为我知道在第一个字段之后我需要使用哪个地址。

有没有更好的方法(我不能改变表的设计)?

感谢您的想法

2 个答案:

答案 0 :(得分:1)

这里真正的问题是user_addressesalternate_addresses是不同的表格。因为它们是不同的表,所以很难让SQL统一对待它们。

拥有单个地址表可以更好的设计,可以由用户和(可选)通过订单引用,然后您就可以设计一个JOIN条件,该条件连接到每个订单的正确地址。

答案 1 :(得分:1)

SELECT a.firstname AS firstname, a.lastname AS lastname, ...
FROM orders
JOIN alternate_addresses a ON (orders.alternate_address_id = a.alternate_address_id)

UNION

SELECT u.firstname AS firstname, u.lastname AS lastname, ...
FROM orders
LEFT JOIN user_addresses u ON (orders.user_id = u.user_id)
WHERE orders.alternate_address_id IS NULL

实际上,drquicksilver有重点。最好有addresses表,地址类型的附加列(主要,替代,还有什么?)。现在不需要alternate_address_id,而是您引用用户的其中一个地址。 FOREIGN KEY (user_id, address_id) REFERENCES addresses (user_id, address_id),或者这些内容。