加入三个表以获得特定结果

时间:2018-11-05 13:39:02

标签: sql oracle join

我有三个表:

表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

2 个答案:

答案 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