Предложение Left Join Where (идентификатор соответствия имени из другой таблицы)

#mysql #sql

#mysql #sql

Вопрос:

Я хочу, чтобы на выходе были указаны день рождения, имя и фамилия клиентов, которых обслуживал Дэвид, у которого идентификатор сотрудника равен 1. Но по какой-то причине (и это может быть очевидно, я только новичок) он выводит только одну строку Victor, c_id которой совпадает с e_id (я знаю, что подсказка где-то там, но не могу понять).

Как мне заставить это работать?

 CREATE TABLE customers (
    birth_day date,
    first_name VARCHAR(20),
    last_name VARCHAR(20),
    c_id int,
    CONSTRAINT PK_Customers PRIMARY KEY (c_id));
INSERT INTO customers (birth_day, first_name, last_name, c_id) VALUES ('1993-07-11','Victor','Davis',1);
INSERT INTO customers (birth_day, first_name, last_name, c_id) VALUES ('2001-03-28','Katarina','Williams',2);
INSERT INTO customers (birth_day, first_name, last_name, c_id) VALUES ('1965-12-11','David','Jones',3);
INSERT INTO customers (birth_day, first_name, last_name, c_id) VALUES ('1980-10-10','Evelyn','Lee',4);


CREATE TABLE employees (
    birth_day date,
    first_name VARCHAR(20),
    last_name VARCHAR(20),
    e_id int,
    CONSTRAINT PK_Employees PRIMARY KEY (e_id)
);
INSERT INTO employees (birth_day, first_name, last_name, e_id) VALUES ('1983-09-02','David','Smith',1);
INSERT INTO employees (birth_day, first_name, last_name, e_id) VALUES ('1990-07-23','Olivia','Brown',2);
INSERT INTO employees (birth_day, first_name, last_name, e_id) VALUES ('1973-05-11','David','Johnson',3);
INSERT INTO employees (birth_day, first_name, last_name, e_id) VALUES ('1999-11-21','Mia','Taylor',4);

CREATE TABLE transactions (
    e_id int,
    c_id int,
    date date,
    t_id int,
    CONSTRAINT PK_transactions PRIMARY KEY (t_id),
    FOREIGN KEY (e_id) REFERENCES employees(e_id),
    FOREIGN KEY (c_id) REFERENCES customers(c_id)
);
INSERT INTO transactions (e_id, c_id, date, t_id) VALUES (1,1,'2020-8-11',1);
INSERT INTO transactions (e_id, c_id, date, t_id) VALUES (3,1,'2020-8-15',2);
INSERT INTO transactions (e_id, c_id, date, t_id) VALUES (1,4,'2020-9-01',3);
INSERT INTO transactions (e_id, c_id, date, t_id) VALUES (2,2,'2020-9-07',4);
INSERT INTO transactions (e_id, c_id, date, t_id) VALUES (4,3,'2020-9-07',5);

CREATE VIEW DavidSoldTo AS 
    SELECT DISTINCT birth_day, first_name, last_name
    FROM customers
    LEFT JOIN transactions on customers.c_id = transactions.e_id 
    WHERE e_id = '1'
    ORDER  BY birth_day
;
 

Комментарии:

1. = transactions.c_id

Ответ №1:

EXISTS это гораздо лучший способ выразить это:

 CREATE VIEW DavidSoldTo AS 
    SELECT c.birth_day, c.first_name, c.last_name
    FROM customers c 
    WHERE EXISTS (SELECT 1
                  FROM transactions t
                  WHERE t.c_id = c.c_id AND t.e_id = 1
                 )
    ORDER BY c.birth_day ;
 

Примечания:

  • JOIN Условия теперь правильные, используя c_id (хотя в этой версии условия находятся в предложении корреляции.
  • Вам не нужно SELECT DISTINCT , потому что дубликаты не создаются, когда «Дэвид» обслуживал кого-то более одного раза. Это большой выигрыш в производительности.
  • e_id это число, поэтому сравнение должно быть с числом ( 1 ), а не со строкой ( '1' ).