如何将多个表的结果与不同的列组合在一起?

时间:2010-10-26 19:21:43

标签: php mysql join union

我有几个包含不同数量和类型的列的表,以及一个共同的列。

+--------+---------+------------+-------------+
| 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行。

5 个答案:

答案 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子句来组合每个查询的结果 - 但是你将不得不解析每一行..数据类型将丢失。