Присоединяйтесь к нескольким таблицам в MySQL

у меня три стола

sem1
--------------------------
roll | sub1 | sub2 | gpa |
--------------------------
001  | 98   | 99   | 8.5 |
002  | 99   |100   | 9.9 |
--------------------------

sem2
--------------------------
roll | sub3 | sub4 | gpa |
--------------------------
001  | 88   | 87   | 8.1 |
002  | 89   | 90   | 9.0 |
-------------------------- 

sem3
--------------------------
roll | sub5 | sub6 | gpa |
--------------------------
001  | 85   | 75   | 8.5 |
002  | 90   | 80   | 8.9 |
--------------------------

Я хочу получить только столбцы рулона и gpa во всех трех таблицах определенного номера рулона (скажем, 001), как это.

-------------------------
|roll | gpa | gpa |gpa  |
-------------------------
| 001 | 8.5 | 8.1 | 8.5 |
-------------------------

Я написал следующий запрос

select roll,gpa,gpa,gpa 
    from sem1 natural 
    join sem2 natural 
    join sem3 
    where roll=001;

Но это не работает. Какие-либо предложения?


person HariS    schedule 07.05.2020    source источник
comment
Начните с пересмотра схемы. У вас должна быть 1 таблица вместо 3... (студент, семестр, предмет, средний балл)   -  person Strawberry    schedule 07.05.2020
comment
Не используйте естественные соединения (никогда) используйте определенные левые соединения   -  person P.Salmon    schedule 07.05.2020


Ответы (1)


При естественном соединении у вас должен быть уникальный столбец в каждой таблице - у вас его нет, gpa одинаков, поэтому естественное соединение выполняется, а gpa an, поскольку gpa отличается, вы ничего не получаете.

если бы ваши таблицы выглядели так

DROP TABLE IF EXISTS SEM1,SEM2,SEM3;
CREATE TABLE SEM1(roll INT primary key, sub1 INT, sub2 INT, gpa DECIMAL(10,2));
CREATE TABLE SEM2(roll INT primary key, sub3 INT, sub4 INT, gpa2 DECIMAL(10,2));
CREATE TABLE SEM3(roll INT primary key, sub5 INT, sub6 INT, gpa3 DECIMAL(10,2));

INSERT INTO sem1 VALUES
(001  , 98   , 99   , 8.5 ),
(002  , 99   ,100   , 9.9 );

INSERT INTO sem2 VALUES
(001  , 88   , 87   , 8.1 ),
(002  , 89   , 90   , 9.0 );

INSERT INTO sem3 VALUES
(001  , 85   , 75   , 8.5 ),
(002  , 90   , 80   , 8.9 );

Тогда ваш запрос (с поправками) даст результат -

select roll,gpa,gpa2,gpa3 
    from sem1 natural 
    join sem2 natural 
    join sem3 
    where roll=001;

+------+------+------+------+
| roll | gpa  | gpa2 | gpa3 |
+------+------+------+------+
|    1 | 8.50 | 8.10 | 8.50 |
+------+------+------+------+
1 row in set (0.001 sec)

Для ясности лучше всего указать имена столбцов, например

select SEM1.roll,SEM1.gpa,SEM2.gpa2,SEM3.gpa3 
from sem1 
natural join sem2 
natural join sem3 
where SEM1.roll=001;

Но не используйте естественные соединения, например, используйте левые соединения.

select SEM1.roll,SEM1.gpa,SEM2.gpa2,SEM3.gpa3 
from sem1 
left join sem2 on sem1.roll = sem2.roll
left join sem3 on sem1.roll = sem3.roll
where SEM1.roll=001;

но даже это, на мой взгляд, недостаточно надежно, поскольку оно опирается на управление sem1 и всегда содержит все различные числа бросков, содержащиеся в sem2 и sem3. Более строгий подход состоял бы в том, чтобы получить все отдельные номера рулонов из всех трех таблиц и двигаться по ним.

person P.Salmon    schedule 07.05.2020