объединить три таблицы для конкретного результата - PullRequest
0 голосов
/ 05 ноября 2018

У меня есть три таблицы:

Таблица 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 голосов
/ 05 ноября 2018

В вашем примере данных говорится о внешних ключах, но таблица 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
0 голосов
/ 05 ноября 2018

A 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...