MYSQL内部加入2个ON子句

时间:2009-11-18 04:09:17

标签: mysql sql join phpmyadmin inner-join

我正在尝试设置一个简单的数据库,其中我有一个用户并存储他们的住宅和邮政地址。我有2张桌子

用户

id (Primary Key)    
name (Varchar 255)
residential_id (foreign key)
postal_id (foreign key)

地址

id (primary key)
type (enum of R and P)
street (varchar 255)
suburb (varchar 255)

我想要进行内连接,所以我最终会得到一个看起来像的结果集。

id - name - residential_street - residential_suburb,postal_street,postal_suburb

我一直得到地址详细信息的空结果,我认为这是因为我从地址表中获取了两组数据并且存在冲突。是否可以同时返回链接到住宅ID和邮政ID的地址字段?

我的SQL语法是

SELECT * FROM users 
LEFT JOIN address
ON (users.residential_id = address.id AND users.postal_id = address.id)

EDIT。正如已经指出的那样,我的数据库设计相当差,我正在寻求改进它。 我想要达到的关键是我可以存储一个人的详细信息以及他们相关的住宅和邮政地址。我永远不会想要扩展数据库以包含工作地址,例如希望这样可以减少表格的复杂性。

4 个答案:

答案 0 :(得分:2)

以下假设

  1. 地址中的“id”列是用户表的外键。
  2. 地址表中有一个addressType列,用于区分邮政与居住地
  3. 你想要的是:

    select 
      u.*, 
      res.street residential_street,
      res.suburb residential_suburb,
      pos.street postal_street,
      pos.suburb postal_suburb
    from users u
        left join address res on u.id=res.id and res.addressType='R'
        left join address pos on u.id=pos.id and pos.addressType='P'
    

    这里的关键是你必须加入地址表TWICE。需要地址类型鉴别符,以便每个连接仅选择适当类型的地址。 如果您的架构不同,请澄清,我将修改我的答案。

答案 1 :(得分:0)

您正在检查列地址是否等于id,我认为在任何情况下都不会这样。

答案 2 :(得分:0)

这相对容易。您只需要加入地址表两次。

SELECT u.id,
       u.name,
       ar.street residential_atreet,
       ar.suburb residential_suburb,
       ap.street postal_street,
       ap.suburb postal_suburb
FROM users u
LEFT JOIN address ar ON u.residential = ar.id
LEFT JOIN address ap ON u.postal = ap.id

这种数据模型不是我个人青睐的。相反,我建议使用地址类型字段并具有一对多关系(地址表中的user.id外键)。

您将面临的一个问题是确定用户对地址的所有权并非严格简单(在您的模型中)。也没有找到孤立的地址。

一个建议:由于住宅和邮政是外键,请尝试将其命名为(例如residential_id和postal_id),以便在阅读SQL时更清楚。

答案 3 :(得分:0)

@ m3mbran3我的建议是转储residential_id&来自用户的postal_id字段

用户

id (Primary Key)    
name (Varchar 255)

<强>地址

id (if required, otherwise primary key is combo of userid,type)
user_id
type (enum of R and P)
street (varchar 255)
suburb (varchar 255)

然后你回到了

SELECT u.id,
       u.name,
       ar.street residential_street,
       ar.suburb residential_suburb,
       ap.street postal_street,
       ap.suburb postal_suburb
FROM users u
LEFT JOIN address ar 
           ON u.id = ar.user_id
           AND ar.type = 'R'
LEFT JOIN address ap 
           ON u.id = ap.user_id
           AND ap.type = 'P'

@Cletus建议的变体。请记住,如果用户有住址并且没有邮政地址,反之亦然,则可能存在空值