我有三个表:
表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 |
+-----------------+--------------+
我需要连接三个表,以便仅当三个表中的CR_AR
值相同时才可以从STRUCT
表中获取数据。
这是我编写的SQL查询,但即使user_struct
中的USERS
不等于STRUCT
中的CR_AR
,它似乎也会返回所有数据
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
答案 0 :(得分:3)
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
答案 1 :(得分:0)
您的数据示例讨论了外键,但是表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