#mysql
#mysql
Вопрос:
Ниже приведен мой запрос, и я хочу получить результат, как указано ниже. Как я могу это сделать в mysql?
SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo
FROM Persons
FULL JOIN Orders
ON Persons.P_Id=Orders.P_Id
ORDER BY Persons.LastName
Набор результатов должен выглядеть следующим образом:
LastName FirstName OrderNo
Hansen Ola 22456
Hansen Ola 24562
Pettersen Kari 77895
Pettersen Kari 44678
Svendson Tove
34764
Комментарии:
1. Вы можете проголосовать за то, чтобы эта функция была реализована в MySQL
Ответ №1:
MySQL не поддерживает ПОЛНОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ.
Итак, если вы хотите эмулировать полное объединение в MySQL, посмотрите здесь .
Обычно предлагаемое обходное решение выглядит следующим образом:
SELECT t_13.value AS val13, t_17.value AS val17
FROM t_13
LEFT JOIN
t_17
ON t_13.value = t_17.value
UNION ALL
SELECT t_13.value AS val13, t_17.value AS val17
FROM t_13
RIGHT JOIN
t_17
ON t_13.value = t_17.value
WHERE t_13.value IS NULL
ORDER BY
COALESCE(val13, val17)
LIMIT 30
Комментарии:
1. Как упорядочить все реестры по одному столбцу?
Ответ №2:
Есть несколько методов для полного ПОЛНОГО [ВНЕШНЕГО] СОЕДИНЕНИЯ mysql.
-
ОБЪЕДИНЕНИЕ левого соединения и правого соединения. ОБЪЕДИНЕНИЕ удалит дубликаты, выполнив операцию ORDER BY. Поэтому, в зависимости от ваших данных, это может быть неэффективно.
SELECT * FROM A LEFT JOIN B ON A.key = B.key UNION SELECT * FROM A RIGHT JOIN B ON A.key = B.key
-
ОБЪЕДИНИТЕ ВСЕ левое соединение и правое, ИСКЛЮЧАЯ соединение (это нижний правый рисунок на диаграмме). ОБЪЕДИНЕНИЕ ВСЕХ не приведет к удалению дубликатов. Иногда это может быть поведение, которое вы хотите. Вы также хотите использовать ПРАВОЕ ИСКЛЮЧЕНИЕ, чтобы избежать дублирования общих записей из выборки A и выборки B — т.е. Левое соединение уже включило общие записи из выборки B, давайте не будем повторять это снова с правым соединением.
SELECT * FROM A LEFT JOIN B ON A.key = B.key UNION ALL SELECT * FROM A RIGHT JOIN B ON A.key = B.key WHERE A.key IS NULL
Ответ №3:
SELECT p.LastName, p.FirstName, o.OrderNo
FROM persons AS p
LEFT JOIN
orders AS o
ON o.orderNo = p.p_id
UNION ALL
SELECT NULL, NULL, orderNo
FROM orders
WHERE orderNo NOT IN
(
SELECT p_id
FROM persons
)
Комментарии:
1. Как упорядочить все реестры по одному столбцу?
2. @Luitame: это должен быть другой вопрос, а не комментарий.
Ответ №4:
Попробуйте это:
(SELECT p.LastName, p.FirstName, o.OrderNo
FROM Persons p
LEFT JOIN Orders o
ON o.OrderNo = p.P_id
)
UNION
(SELECT p.LastName, p.FirstName, o.OrderNo
FROM Persons p
RIGHT JOIN Orders o
ON o.OrderNo = p.P_id
);
---------- ----------- ---------
| LastName | FirstName | OrderNo |
---------- ----------- ---------
| Singh | Shashi | 1 |
| Yadav | Sunil | NULL |
| Singh | Satya | NULL |
| Jain | Ankit | NULL |
| NULL | NULL | 11 |
| NULL | NULL | 12 |
| NULL | NULL | 13 |
---------- ----------- ---------
Комментарии:
1. Важно соблюдать то, что
UNION
используется, а неUNION ALL
2. Здесь используется ОБЪЕДИНЕНИЕ, которое удалит дубликаты и выполнит операцию сортировки. Если вам нужен более производительный запрос или вы хотите сохранить дубликаты, используйте UNION ALL .
Ответ №5:
Хм, объединение ЛЕВОГО и ПРАВОГО СОЕДИНЕНИЯ с ОБЪЕДИНЕНИЕМ может сделать это:
SELECT p.LastName, p.FirstName, o.OrderNo
FROM persons AS p
LEFT JOIN
orders AS o
ON p.P_Id = Orders.P_Id
UNION ALL
SELECT p.LastName, p.FirstName, o.OrderNo
FROM persons AS p
RIGHT JOIN
orders AS o
ON p.P_Id = Orders.P_Id
WHERE p.P_Id IS NULL
Ответ №6:
Полное объединение в mysql: (левое объединение справа) или (правое объединение слева)
SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo
FROM Persons
left JOIN Orders
ON Persons.P_Id=Orders.P_Id
ORDER BY Persons.LastName
Union
SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo
FROM Persons
Right JOIN Orders
ON Persons.P_Id=Orders.P_Id
ORDER BY Persons.LastName
Комментарии:
1. Здесь используется ОБЪЕДИНЕНИЕ, которое удалит дубликаты и выполнит операцию сортировки. Если вам нужен более производительный запрос или вы хотите сохранить дубликаты, используйте ОБЪЕДИНЕНИЕ ВСЕХ
Ответ №7:
Другой альтернативой является использование временной таблицы и ВСТАВКИ ДУБЛИРУЮЩЕГО КЛЮЧА, подобного этому.
Создание образца данных:
CREATE TABLE A (
AKEY INT PRIMARY KEY,
AVALUE DOUBLE
);
INSERT INTO A VALUES(1, 0.1);
INSERT INTO A VALUES(2, 0.2);
CREATE TABLE B (
BKEY INT PRIMARY KEY,
BVALUE DOUBLE
);
INSERT INTO B VALUES(2, 0.2);
INSERT INTO B VALUES(3, 0.3);
Таблица данных:
AKEY|AVALUE|
---- ------
1| 0.1|
2| 0.2|
Данные таблицы B:
BKEY|BVALUE|
---- ------
2| 0.2|
3| 0.3|
Создание временной таблицы:
CREATE TEMPORARY TABLE ABFULLJOIN (
ABKEY INT PRIMARY KEY,
AVALUE DOUBLE,
BVALUE DOUBLE
);
ВСТАВИТЬ В оператор ДУБЛИРОВАНИЯ КЛЮЧА:
INSERT INTO ABFULLJOIN(ABKEY, AVALUE)
SELECT * FROM A;
INSERT INTO ABFULLJOIN(ABKEY, BVALUE)
SELECT * FROM B ON DUPLICATE KEY UPDATE BVALUE = B.BVALUE ;
Запрос ПОЛНОГО СОЕДИНЕНИЯ:
SELECT * FROM ABFULLJOIN;
Результат:
ABKEY|AVALUE|BVALUE|
----- ------ ------
1| 0.1| |
2| 0.2| 0.2|
3| | 0.3|
УДАЛИТЬ временную таблицу:
DROP TABLE ABFULLJOIN;
Ответ №8:
Здесь все правильно, но писать один и тот же запрос дважды — не очень хороший способ программирования… итак, у меня есть другой способ выполнить полное объединение в mysql, который заключается в следующем
SELECT
user_id , user_name, user_department
FROM
(SELECT
user_id , user_name , NULL as user_department
FROM
tb_users
UNION
SELECT
user_id ,NULL as user_name , user_department
FROM
tb_departments
) as t group by user_id