我有几个包含不同数量和类型的列的表,以及一个共同的列。
+--------+---------+------------+-------------+
| person | beardID | beardStyle | beardLength |
+--------+---------+------------+-------------+
+--------+-------------+----------------+
| person | moustacheID | moustacheStyle |
+--------+-------------+----------------+
我想获取与共享列的给定值匹配的所有结果。我可以使用这样的多个select语句来做到这一点:
SELECT * FROM beards WHERE person = "bob"
和
SELECT * FROM moustaches WHERE person = "bob"
但这需要多次mysql API调用,这似乎效率低下。我希望我可以使用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行。
答案 0 :(得分:7)
这应该可以正常工作:
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)
这是我做的本地测试
答案 1 :(得分:0)
加入人......
即。
选择 t1。(asterix),t2。(asterix) 从 胡须t1 内部联接 胡须t2在t2.person = t1.person
答案 2 :(得分:0)
SELECT *
FROM beards
JOIN moustaches
ON moustaches.person = beards.person
WHERE person = "bob"
答案 3 :(得分:0)
我玩得很开心,不确定它是否完全可以管理你需要添加的东西,但它完成了目标。
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
答案 4 :(得分:0)
我认为通过查询每个表中的数据会更好。
其他一种可能性是将所有列的数据连接成一个大字符串(你可以选择一些符号来分隔列的值),然后你应该能够使用union all子句来组合每个查询的结果 - 但是你将不得不解析每一行..数据类型将丢失。