У меня есть несколько таблиц с разными номерами и типами столбцов и один столбец.
+--------+---------+------------+-------------+ | person | beardID | beardStyle | beardLength | +--------+---------+------------+-------------+ +--------+-------------+----------------+ | person | moustacheID | moustacheStyle | +--------+-------------+----------------+
Я хочу получить все результаты, соответствующие заданному значению общего столбца. Я могу сделать это, используя несколько операторов select, таких как:
SELECT * FROM beards WHERE person = "bob"
а также
SELECT * FROM moustaches WHERE person = "bob"
Но для этого требуется несколько вызовов API mysql, что кажется неэффективным. Я надеялся, что смогу использовать UNION ALL, чтобы получить все результаты в одном вызове API, но UNION требует, чтобы таблицы имели одинаковый номер и аналогичный тип столбцов. Я мог бы написать инструкцию SELECT, которая вручную помещала бы результаты из каждой таблицы, добавляя столбцы с значениями NULL, но это быстро стало бы неуправляемым для нескольких таблиц с несколькими столбцами.
Я ищу набор результатов примерно так:
+--------+---------+------------+-------------+-------------+----------------+ | person | beardID | beardStyle | beardLength | moustacheID | moustacheStyle | +--------+---------+------------+-------------+-------------+----------------+ | bob | 1 | rasputin | 1 | | | +--------+---------+------------+-------------+-------------+----------------+ | bob | 2 | samson | 12 | | | +--------+---------+------------+-------------+-------------+----------------+ | bob | | | | 1 | fu manchu | +--------+---------+------------+-------------+-------------+----------------+
Есть ли способ достичь этого, что быстро и удобно? Или мне лучше запускать отдельный запрос для каждой таблицы?
Разъяснение:
Я не ищу декартовую продукцию. Мне не нужна строка для каждой комбинации бород и усов, мне нужна строка для каждой бороды и строки для каждого уса.
Так что, если есть 3 подходящие бороды и 2 подходящих уса, я должен получить 5 строк, а не 6.
это должно работать нормально:
SELECT * FROM `beards` b LEFT OUTER JOIN `mustaches` ON (0) WHERE person = "bob" UNION ALL SELECT * FROM `beards` b RIGHT OUTER JOIN `mustaches` ON (0) WHERE person = "bob"
вам не нужно обрабатывать столбцы самостоятельно. левое и правое внешнее соединение выполняют эту работу. к сожалению, mysql не имеет полного соединения. поэтому вы должны сделать это таким образом с объединением
SELECT * FROM `customer` b LEFT OUTER JOIN `charges` ON (0) LEFT OUTER JOIN `day` ON (0) UNION SELECT * FROM `customer` b RIGHT OUTER JOIN `charges` ON (0) LEFT OUTER JOIN `day` ON (0) UNION SELECT * FROM `customer` b LEFT OUTER JOIN `charges` ON (0) RIGHT OUTER JOIN `day` ON (0)
это локальный тест, который я сделал
Присоединяйтесь к человеку ….
Т.е.
Выберите t1. (Asterix), t2. (Asterix) ОТ бород t1 INNER JOIN усы t2 На t2.person = t1.person
SELECT * FROM beards JOIN moustaches ON moustaches.person = beards.person WHERE person = "bob"
Мне было весело с этим, не уверен, что это полностью управляемо с тем, что вам нужно добавить, но оно достигло цели.
create table beard ( person varchar(20) ,beardID int ,beardStyle varchar(20) ,beardLength int ) create table moustache( person varchar(20) ,moustacheID int ,moustacheStyle varchar(20)) insert into beard select 'bob', 1, 'rasputin', 1 union select 'bob', 2, 'samson', 12 insert into moustache select 'bob', 1, 'fu manchu' declare @facialhair table ( person varchar(20) ,beardID int ,beardStyle varchar(20) ,beardLength int ,moustacheID int ,moustacheStyle varchar(20)) declare @i int declare @name varchar(20) set @name = 'bob' set @i = (select COUNT(*) from beard where person = @name) + (select COUNT(*) from moustache where person = @name) print @i while @i > 0 begin insert into @facialhair (person, beardID, beardStyle, beardLength) select person, beardID, beardStyle, beardLength from beard where person = @name set @i = @i-@@ROWCOUNT insert into @facialhair (person, moustacheID, moustacheStyle) select person, moustacheID, moustacheStyle from moustache where person = @name set @i = @i-@@ROWCOUNT end select * from @facialhair
Я думаю, вам было бы лучше сделать запросы для данных в каждой таблице.
Одна из других возможностей состоит в том, чтобы объединить данные из всех столбцов в одну большую строку (вы можете выбрать какой-либо знак для значений столбца separete), тогда вы должны иметь возможность использовать предложение union all для объединения результатов от каждого запроса, но тогда вам придется проанализируйте каждую строку .. И типы данных будут потеряны.