如何合并具有不同列的多个表的结果?

发布于 2024-09-28 19:51:52 字数 1668 浏览 4 评论 0原文

我有几个具有不同数量和类型的列的表,并且有一个共同的列。

+--------+---------+------------+-------------+
| person | beardID | beardStyle | beardLength |
+--------+---------+------------+-------------+

+--------+-------------+----------------+
| person | moustacheID | moustacheStyle |
+--------+-------------+----------------+

我想获取与共享列的给定值匹配的所有结果。我可以使用多个 select 语句来完成,如下所示:

SELECT * FROM beards WHERE person = "bob"

and

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

I have several tables with different numbers and types of columns, and a single column in common.

+--------+---------+------------+-------------+
| person | beardID | beardStyle | beardLength |
+--------+---------+------------+-------------+

+--------+-------------+----------------+
| person | moustacheID | moustacheStyle |
+--------+-------------+----------------+

I want to fetch all the results that match a given value of the shared column. I can do it using multiple select statements like this:

SELECT * FROM beards WHERE person = "bob"

and

SELECT * FROM moustaches WHERE person = "bob"

But this requires multiple mysql API calls, which seems inefficient. I was hoping I could use UNION ALL to get all the results in a single API call, but UNION requires that the tables have the same number and similar type of columns. I could write a SELECT statement that would manually pad the results from each table by adding columns with NULL values, but that would quickly get unmanageable for a few more tables with a few more columns.

I'm looking for a result set roughly like this:

+--------+---------+------------+-------------+-------------+----------------+
| person | beardID | beardStyle | beardLength | moustacheID | moustacheStyle |
+--------+---------+------------+-------------+-------------+----------------+
| bob    | 1       | rasputin   | 1           |             |                |
+--------+---------+------------+-------------+-------------+----------------+
| bob    | 2       | samson     | 12          |             |                |
+--------+---------+------------+-------------+-------------+----------------+
| bob    |         |            |             | 1           | fu manchu      |
+--------+---------+------------+-------------+-------------+----------------+

Is there a way to achieve this that's fast and maintainable? Or am I better off running a separate query for each table?

Clarification:

I'm not looking for a cartesian product. I don't want a row for every combination of beard-and-moustache, I want a row for every beard and a row for every moustache.

So if there are 3 matching beards and 2 matching moustaches I should get 5 rows, not 6.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

何以笙箫默 2024-10-05 19:51:52

这应该工作正常:

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)

这是我所做的本地测试

this should be working fine:

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"

you don't have to handle the columns by yourself. the left and right outer join do this job.
unfortunately mysql doesn't have a full join. that's why you have to do it this way with a union

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)

this is a local test i made

总以为 2024-10-05 19:51:52

加入人员....

选择
t1.(星号),t2.(星号)

胡须t1
内连接
小胡子 t2 在 t2.person = t1.person 上

Join on person....

I.e.

Select
t1.(asterix), t2.(asterix)
FROM
beards t1
INNER JOIN
moustaches t2 On t2.person = t1.person

旧竹 2024-10-05 19:51:52
SELECT *
FROM   beards
       JOIN moustaches
         ON moustaches.person = beards.person
WHERE  person = "bob"  
SELECT *
FROM   beards
       JOIN moustaches
         ON moustaches.person = beards.person
WHERE  person = "bob"  
你的心境我的脸 2024-10-05 19:51:52

我对此很感兴趣,不确定它是否完全可以管理,您还需要添加更多内容,但它实现了目标。

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

I had fun with this, not sure it's entirely manageable with what more you have to add, but it accomplished the goal.

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
酒浓于脸红 2024-10-05 19:51:52

我认为你通过查询每个表中的数据会更好。

另一种可能性是将所有列中的数据连接成一个大字符串(您可以选择一些符号来分隔列的值),然后您应该能够使用 union all 子句来组合每个查询的结果 - 但随后您将不得不解析每一行..并且数据类型将丢失。

I think you would be better by making queries for data in each table.

One of other possibilities is to concatenate data from all columns into one big string (you could choose some sign to separete column's values), then you should be able to use union all clause to combine results from each query - but then you will have to parse each row.. And data types will be lost.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文