1

我正在尝试设置一个简单的数据库,其中有一个用户并存储他们的居住地址和邮政地址。我有 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 - 名称 - 住宅街道 - 住宅郊区、邮政街道、邮政郊区

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

我的 SQL 语法是

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

编辑。正如已经指出的那样,我的数据库设计相当糟糕,我正在寻求改进它。我想要实现的关键是我可以存储一个人的详细信息以及他们相关的住宅和邮政地址。我永远不会寻求扩展数据库以包含例如工作地址,因此希望能够降低表格的复杂性。

4

4 回答 4

3

以下假设

  1. 地址中的“id”列是用户表的外键。
  2. 地址表中有一个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'

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

于 2009-11-18T04:25:57.823 回答
0

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

于 2009-11-18T04:11:27.020 回答
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 外键)。

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

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

于 2009-11-18T04:14:45.490 回答
0

@m3mbran3 我的建议是从用户中转储住宅 ID 和邮政 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 建议的变体。请记住,如果用户有居住地址而没有邮政地址,反之亦然,则可能为空

于 2009-11-18T05:43:11.380 回答