MYSQL内部连接2 ON子句

MYSQL内部连接2 ON子句,mysql,sql,join,phpmyadmin,inner-join,Mysql,Sql,Join,Phpmyadmin,Inner Join,我试图建立一个简单的数据库,在其中我有一个用户,并存储他们的住宅和邮政地址。我有两张桌子 用户 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 (Primary Key) name

我试图建立一个简单的数据库,在其中我有一个用户,并存储他们的住宅和邮政地址。我有两张桌子

用户

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 (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)
地址

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 (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)
我尝试进行一个内部联接,因此最终得到的结果集如下所示

id-名称-住宅区街道-住宅区郊区、邮政区街道、邮政区郊区

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

我的SQL语法是

SELECT * FROM users 
LEFT JOIN address
ON (users.residential_id = address.id AND users.postal_id = address.id)
编辑。正如已经指出的那样,我的数据库设计相当差,我希望改进它。
我试图实现的关键是,我可以存储一个人的详细信息以及他们相关的住宅和邮政地址。我永远不会希望扩展数据库以包含工作地址,例如,希望这样可以降低表的复杂性。

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

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

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外键)

您将面临的一个问题是(在您的模型中)确定地址的用户所有权并不是非常简单的。寻找孤立地址也是如此


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

以下假设:

  • 地址中的“id”列是用户表的外键
  • 地址表中有一个addressType列,用于区分邮寄地址和居住地址
  • 你想要的是:

    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'
    
    这里的关键是你必须加入地址表两次。需要地址类型鉴别器,以便每个连接只选择适当的地址类型。
    如果您的模式不同,请澄清,我将修改我的答案。

    @m3mbran3我的建议是从用户处转储住宅id和邮政id字段

    用户

    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 (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)
    
    地址

    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 (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建议的变体。请记住,如果用户有居住地址而没有邮政地址,或者反之亦然,则可能会有空值

    请显示一些示例数据。@Olafur:这与他的数据不一样吗?有什么不同?是的,地址表的主键是(id,addressType)。在最初的版本中,我觉得地址中的id存储在User.Residential或User.Postal字段中,这让我觉得设计很糟糕。例如,添加一个新的工作地址将意味着更改用户表。Murf和Jim,你是正确的,因为我的初始设计最好是糟糕的,因此如果您能为我提供更好的设计,我将不胜感激。您的查询假设我有一个单独的居住地址和邮政地址表。实际上,我只有一个类型字段,表示它是住宅还是邮政。但正如我在编辑的问题中所说,我目前正在研究如何更好地设计我的(应该是什么样的)相对简单的数据库。