连接三个表以获得特定结果
Posted
技术标签:
【中文标题】连接三个表以获得特定结果【英文标题】:join three tables for specific result 【发布时间】:2018-11-05 13:39:02 【问题描述】:我有三张桌子:
表 1 Users
:
+----------+------------+------------+-------------------+
| ID [PK] | username | password | user_struct [FK] |
+----------+------------+------------+-------------------+
| 1 | SAM | 123 | CIF |
| 2 | JACK | 123 | ADM |
| 3 | JAMAL | 123 | SDT |
+----------+------------+------------+-------------------+
表 2 CR_AR
:
+-------------+-------+--------------+
| ID_CR [PK] | NUM | STRUCT [FK] |
+-------------+-------+--------------+
| 1 | 11 | CIF |
| 2 | 22 | ADM |
| 3 | 33 | SDT |
+-------------+-------+--------------+
表 3 STRUCT
:
+-----------------+--------------+
| STRUCTURE [PK] | description |
+-----------------+--------------+
| CIF | NULL |
| IDM | NULL |
| SDT | NULL |
+-----------------+--------------+
我需要连接三个表,以便只有当三个表中的STRUCT
值相同时,我才能从CR_AR
表中获取数据。
这是我编写的 SQL 查询,但它似乎返回所有数据,即使 USERS
中的 user_struct
不等于 CR_AR
中的 STRUCT
SELECT * FROM CR_AR AS C
LEFT JOIN STRUCT AS S ON S.STRUCTURE = C.STRUCT
LEFT JOIN USERS AS U ON U.USER_STRUCT = S.STRUCTURE
【问题讨论】:
把所有的“Left join”改成“Join” 你为什么使用左连接?你看过第一次左连接后的结果吗? (绝对是基本的调试。)你明白左连接返回内连接行加上空值扩展的不匹配左表行吗? 【参考方案1】:LEFT JOIN
将始终返回连接 左侧 表中的 所有 记录,并且仅返回与连接表中的连接条件匹配的记录中的值连接的右侧。
要仅返回为每条记录验证了连接条件的记录,您应该使用INNER JOIN
,即:
SELECT *
FROM
CR_AR C
INNER JOIN STRUCT S ON S.STRUCTURE = C.STRUCT
INNER JOIN USERS U ON U.USER_STRUCT = S.STRUCTURE
【讨论】:
对!但即使 CR_AR 中的 STRUCT 不等于 USER 中的 STRUCT,查询仍会返回所有数据 SAM 的示例我希望它只返回 1 | 11 不是CR_AR的全部数据 @YOUCEFsami 请提供完整的示例数据并显示您在运行查询时获得的结果。 @YOUCEFsami Lee 的查询将只返回来自 CR_AR 的 Users.username='SAM' 的 1/11 行。在您提出问题之前,您是否尝试过运行它?【参考方案2】:您的数据示例谈到了外键,但表 STRUCT 不包含 ADM,而是 IDM。所以那里有些不一致。
如果您不想返回所有行,则不应使用外连接。请改用内部连接。
根据您的示例,这是我的测试,其中包含一些您可能会发现有用的建议查询:
create table users (
id int,
username varchar(10),
pwd varchar(10),
user_struct varchar(3)
)
create table cr_ar (
id int,
num int,
struct varchar(3)
)
create table struct (
structure varchar(3),
description varchar(10)
)
insert into users values (1, 'sam', 123, 'CIF')
insert into users values (2, 'jack', 123, 'ADM')
insert into users values (3, 'jamal', 123, 'SDT')
insert into cr_ar values (1, 11, 'CIF')
insert into cr_ar values (2, 22, 'ADM')
insert into cr_ar values (3, 33, 'SDT')
insert into struct values ('CIF', null)
insert into struct values ('IDM', null)
insert into struct values ('SDT', null)
-- your query
SELECT * FROM CR_AR AS C
LEFT JOIN STRUCT AS S ON S.STRUCTURE = C.STRUCT
LEFT JOIN USERS AS U ON U.USER_STRUCT = S.STRUCTURE
-- no outer joins
SELECT * FROM CR_AR AS C
JOIN STRUCT AS S ON S.STRUCTURE = C.STRUCT
JOIN USERS AS U ON U.USER_STRUCT = S.STRUCTURE
-- alternative with outer joins (showing struct ADM does not exist)
SELECT * FROM CR_AR AS C
LEFT JOIN USERS AS U ON U.USER_STRUCT = C.struct
LEFT JOIN struct AS s ON s.structure = c.struct
【讨论】:
对不起,是ADM,写错了,表STRUCT包含ADM 那我不明白你说“USERS 中的 user_struct 不等于 CR_AR 中的 STRUCT”。在您的示例中,两个表在其“结构”列中包含相同的值集。以上是关于连接三个表以获得特定结果的主要内容,如果未能解决你的问题,请参考以下文章