带有 2 个 ON 子句的 MYSQL 内连接

发布于 2024-08-11 07:43:09 字数 813 浏览 1 评论 0原文

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

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

I am trying to setup a simple database in which I have a user and store both their residential and postal address. I have 2 tables

Users

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

Address

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

I am tring to do an inner join so I end up with a result-set that looks like.

id - name - residential_street - residential_suburb, postal_street, postal_suburb

I keep getting null results for the address details, I assume this is because I am getting two sets of data from the address table and there is a conflict. Is it possible to return the address fields linked to the residential ID and the postal ID at the same time?

My SQL syntax is

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

EDIT. As has been pointed out my DB design is rather poor and I am looking to improve it.
The key thing I am trying to achieve is that I can store the details of a person along with their associated residential and postal address. I will never be looking to expand the database to include a work address for example so hopefully that cuts down the complexity of the table.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

少女净妖师 2024-08-18 07:43:09

下面假设

  1. 地址中的“id”列是用户表的外键。
  2. 地址表中有一个地址类型列,用于区分邮政和居住。

您想要的是:

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'

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

The following assumes that

  1. the "id" column in the address is the foreign key to the user table.
  2. there is an addressType column in the address table that distinguishes postal from residence

What you want is:

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'

The key here is you have to join to the address table TWICE. The address type discriminator is needed so that each join selects only the appropriate type of address.
If your schema is different, please clarify and I'll modify my answer.

揪着可爱 2024-08-18 07:43:09

您正在检查列地址是否等于 id,我认为无论如何这都不是真的。

You're checking if the column address is equal to an id, I don't think this will be true in any case.

浅浅淡淡 2024-08-18 07:43:09

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

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 时更清晰。

That's relatively easy. You just need to join to the address table twice.

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

This kind of data model is not one I personally favour. Instead I would suggest having an address type field and having a one-to-many relationship (user.id foreign key in address table).

One problem you'll face is that determining user ownership of addresses isn't strictly straightforward (in your model). Nor is finding orphaned addresses.

One suggestion: since residential and postal are foreign keys, try to name them as such (eg residential_id and postal_id) so it's clearer when reading the SQL.

莫相离 2024-08-18 07:43:09

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

@m3mbran3 my suggestion would be to dump the residential_id & postal_id fields from Users

Users

id (Primary Key)    
name (Varchar 255)

Address

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)

Then you're back to

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'

a variation of @Cletus suggestion. Remembering that if a user has a residential address and no postal address or vice/versa there may be nulls

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文