У меня есть таблица MySQL, которая выглядит так:
Таблица 1
User_ID | Serial | Warranty
1 | 12 | 2024-01-01
4 | 13423 | 2022-11-21
1 | 643r | 2026-05-13
4 | r42r4 | 2023-10-07
5 | 743f | 2026-06-22
6 | 4324 | 2027-04-15
Таблица 2
ID | Name | Side | Serial
1 | Bob | Left | 12
4 | Mark | Right | 13423
1 | Bob | Right | 643r
4 | Mark | Left | r42r4
5 | Ella | Left | 743f
6 | Deb | Right | 4324
Мне нужен запрос, который объединит все детали в один результат, например:
User_ID | Name | Left Warranty | Right Warranty | Left Serial | Right Serial
5 | Ella | 2026-06-22 | null | 743f | null
4 | Mark | 2023-10-07 | 2022-11-21 | r42r4 | 13423
1 | Bob | 2024-01-01 | 2026-05-13 | 12 | 643r
6 | Deb | null | 2027-04-15 | null | 4324
Я знаю, как группировать, но я полностью зациклен на логике объединения этих таблиц в центральный результат запроса со всей объединенной информацией о записях на основе серийных номеров.
Ты прав. Извините, я испортил пример table2. Я сейчас отредактирую. Спасибо, что обратили на это мое внимание.
Для объединения таблиц требуется JOIN
. Размещение левых и правых в своих столбцах — это поворот. Если вы изучите оба из них, вы получите ответ.
Вы хоть что-нибудь пробовали???
Непонятно, что table1 принесет на вечеринку, как сказал Дуг.
Но для примера данных в таблице 2 подойдет простое условное агрегирование. Общий термин для этого — «поворот».
CREATE TABLE table_2 (
ID INT,
Name VARCHAR(50),
Side VARCHAR(5),
Warranty DATE,
Serial VARCHAR(20)
);
INSERT INTO table_2 (ID, Name, Side, Warranty, Serial) VALUES
(1, 'Bob', 'Left', '2024-01-01', '12'),
(4, 'Mark', 'Right', '2022-11-21', '13423'),
(1, 'Bob', 'Right', '2026-05-13', '643r'),
(4, 'Mark', 'Left', '2023-10-07', 'r42r4'),
(5, 'Ella', 'Left', '2026-06-22', '743f'),
(6, 'Deb', 'Right', '2027-04-15', '4324');
select id,
name,
max(case when side = 'Left' then warranty else null end) as left_warranty,
max(case when side = 'Right' then warranty else null end) as right_warranty,
max(case when side = 'Left' then serial else null end) as left_serial,
max(case when side = 'Right' then serial else null end) as right_serial
from table_2
group
by id,
name
Спасибо за ответ. Я отредактировал свое исходное сообщение, так как в таблице 2 по ошибке появился дополнительный столбец!
Объединение сделает свое дело. Измените соединение в соответствии с вашими потребностями. Скрипка
CREATE TABLE User_Warranty
(
User_ID INT NOT NULL
, Serial VARCHAR(50) NOT NULL
, Warranty DATE NOT NULL
, PRIMARY KEY (User_ID, Serial)
);
CREATE TABLE User_Serial
(
ID INT NOT NULL
, Name VARCHAR(50) NOT NULL
, Side VARCHAR(10) NOT NULL
, Serial VARCHAR(50) NOT NULL
, PRIMARY KEY (ID, Serial)
);
INSERT INTO User_Warranty (User_ID, Serial, Warranty) VALUES (1, '12', '2024-01-01');
INSERT INTO User_Warranty (User_ID, Serial, Warranty) VALUES (4, '13423', '2022-11-21');
INSERT INTO User_Warranty (User_ID, Serial, Warranty) VALUES (1, '643r', '2026-05-13');
INSERT INTO User_Warranty (User_ID, Serial, Warranty) VALUES (4, 'r42r4', '2023-10-07');
INSERT INTO User_Warranty (User_ID, Serial, Warranty) VALUES (5, '743f', '2026-06-22');
INSERT INTO User_Warranty (User_ID, Serial, Warranty) VALUES (6, '4324', '2027-04-15');
INSERT INTO User_Serial (ID, Name, Side, Serial) VALUES (1, 'Bob', 'Left', '12');
INSERT INTO User_Serial (ID, Name, Side, Serial) VALUES (4, 'Mark', 'Right', '13423');
INSERT INTO User_Serial (ID, Name, Side, Serial) VALUES (1, 'Bob', 'Right', '643r');
INSERT INTO User_Serial (ID, Name, Side, Serial) VALUES (4, 'Mark', 'Left', 'r42r4');
INSERT INTO User_Serial (ID, Name, Side, Serial) VALUES (5, 'Ella', 'Left', '743f');
INSERT INTO User_Serial (ID, Name, Side, Serial) VALUES (6, 'Deb', 'Right', '4324');
SELECT
us.ID AS User_ID
, us.Name
, MAX(CASE WHEN us.Side = 'Left' THEN uw.Warranty END) `Left Warranty`
, MAX(CASE WHEN us.Side = 'Right' THEN uw.Warranty END) `Right Warranty`
, MAX(CASE WHEN us.Side = 'Left' THEN us.Serial END) `Left Serial`
, MAX(CASE WHEN us.Side = 'Right' THEN us.Serial END) `Right Serial`
FROM User_Serial us
JOIN User_Warranty uw ON us.ID = uw.User_ID AND us.Serial = uw.Serial
GROUP BY us.ID, us.Name;
Вам понадобится OUTER JOIN
и определить объединение двух столбцов (User_ID и Serial), использовать оператор CASE
, чтобы вручную свести данные, а затем каким-то образом агрегировать (я использую MAX()
ниже), чтобы консолидировать результаты и исключить повторяющиеся строки, содержащие NULL.
WITH
table1 (
User_ID
, Serial
, Warranty
) as (
select 1, '12' , DATE '2024-01-01'
union select 4, '13423', DATE '2022-11-21'
union select 1, '643r' , DATE '2026-05-13'
union select 4, 'r42r4', DATE '2023-10-07'
union select 5, '743f' , DATE '2026-06-22'
union select 6, '4324' , DATE '2027-04-15'
),
table2 (
ID
, Name
, Side
, Serial
) as (
select 1, 'Bob' , 'Left' , '12'
union select 4, 'Mark', 'Right', '13423'
union select 1, 'Bob' , 'Right', '643r'
union select 4, 'Mark', 'Left' , 'r42r4'
union select 5, 'Ella', 'Left' , '743f'
union select 6, 'Deb' , 'Right', '4324'
)
select
table2.ID as User_ID
, table2.Name
, max(case when table2.Side = 'Left' then table1.Warranty end) as "Left Warranty"
, max(case when table2.Side = 'Right' then table1.Warranty end) as "Right Warranty"
, max(case when table2.Side = 'Left' then table1.Serial end) as "Left Serial"
, max(case when table2.Side = 'Right' then table1.Serial end) as "Right Serial"
from table2
left outer join table1 on table1.User_ID = table2.ID
and table1.Serial = table2.Serial
group by
table2.ID
, table2.Name
order by 1
Чтобы достичь желаемого результата, вы можете использовать комбинацию операторов LEFT JOIN и CASE для сведения данных на основе столбца Side.
SELECT
t1.User_ID,
t2.Name,
MAX(CASE WHEN t2.Side = 'Left'
THEN t1.Warranty END) AS `Left Warranty`,
MAX(CASE WHEN t2.Side = 'Right'
THEN t1.Warranty END) AS `Right Warranty`,
MAX(CASE WHEN t2.Side = 'Left'
THEN t2.Serial END) AS `Left Serial`,
MAX(CASE WHEN t2.Side = 'Right'
THEN t2.Serial END) AS `Right Serial`
FROM
table1 t1
JOIN
table2 t2 ON t1.Serial = t2.Serial
GROUP BY
t1.User_ID, t2.Name
ORDER BY
t1.User_ID;
Я вообще не понимаю, как table1 играет в это роль. Все данные для вывода находятся в таблице2. Возможно, лучше опишете проблему.