将一行连接到另一个表中的多行

Posted

技术标签:

【中文标题】将一行连接到另一个表中的多行【英文标题】:Join one row to multiple rows in another table 【发布时间】:2011-02-22 23:36:09 【问题描述】:

我有一张实体表(让我们称他们为人)和属性(一个人可以拥有任意数量的属性)。例如:

Name  Age
--------
Jane  27
Joe   36
Jim   16

属性

Name   Property
-----------------
Jane   Smart
Jane   Funny
Jane   Good-looking
Joe    Smart
Joe    Workaholic
Jim    Funny
Jim    Young

我想编写一个高效的选择,根据年龄选择人并返回他们的全部或部分属性。

Ex: People older than 26
Name Properties
Jane Smart, Funny, Good-looking
Joe Smart, Workaholic

也可以返回属性之一和属性总数。

查询应该是高效的:人表有几百万行,属性表有几十万行(所以大多数人没有属性)。一次选择数百行。

有什么办法吗?

【问题讨论】:

您是否正在寻找以逗号分隔的属性列表?另外,您是否需要指定要查看的属性? IE。 “26 岁以上的人,风趣又好看” 【参考方案1】:

用途:

   SELECT x.name,
          GROUP_CONCAT(y.property SEPARATOR ', ')
     FROM PEOPLE x
LEFT JOIN PROPERTIES y ON y.name = x.name
    WHERE x.age > 26
 GROUP BY x.name

您需要 mysql 函数 GROUP_CONCAT (documentation) 以返回 PROPERTIES.property 值的逗号分隔列表。

我使用 LEFT JOIN 而不是 JOIN 来包含 PROPERTIES 表中没有值的 PEOPLE 记录 - 如果您只想要 PROPERTIES 表中具有值的人员列表,请使用:

   SELECT x.name,
          GROUP_CONCAT(y.property SEPARATOR ', ')
     FROM PEOPLE x
     JOIN PROPERTIES y ON y.name = x.name
    WHERE x.age > 26
 GROUP BY x.name

我知道这是一个示例,但是当您考虑到有多少“John Smith”时,使用名称对于引用完整性来说是一个糟糕的选择。分配一个 user_id,作为每个用户的唯一值,将是一个更好的选择。

【讨论】:

@meriton:我希望将 PROPERTIES 表中的两列都作为主键。 对,这比盲目地遵循“每个外键都应该有一个索引”规则更好:-) 如果有人遇到这个问题并且正在使用 Oracle DB,则有一个等效的 LISTAGG 函数(我认为是从 Oracel 11.2 开始):docs.oracle.com/cd/E14072_01/server.112/e10592/functions087.htm @CodeClimber:这个问题被标记为 MySQL,而不是 Oracle。 @OMGPonies 是的,我知道这一点。不想回答这个问题,只是帮助任何最终在 Oracle DB 上进行类似查询的人。【参考方案2】:

您可以使用INNER JOIN 将两个表链接在一起。 More info on JOINs.

SELECT *
FROM People P
INNER JOIN Properties Pr
  ON Pr.Name = P.Name
WHERE P.Name = 'Joe' -- or a specific age, etc

但是,将唯一的primary key 添加到此类表中并创建index 以提高速度通常要快得多。

说表People有一个字段id 而表Properties 有一个字段peopleId 将它们链接在一起

那么查询将如下所示:

SELECT *
FROM People P
INNER JOIN Properties Pr
  ON Pr.id = P.peopleId
WHERE P.Name = 'Joe'

【讨论】:

【参考方案3】:
SELECT x.name,(select GROUP_CONCAT(y.Properties SEPARATOR ', ')
FROM PROPERTIES y 
WHERE y.name.=x.name ) as Properties FROM mst_People x 

试试这个

【讨论】:

以上是关于将一行连接到另一个表中的多行的主要内容,如果未能解决你的问题,请参考以下文章

Wordpress 用户和用户元 - 将一个表中的多行连接到另一个表中的一行

数据库多行拼接到一行Oracle和sqlServer

将一个表中的单行连接到另一个表中的 n 个随机行

如何将一个表中的最新行连接到另一个表?

Oracle - 将一行或多行连接到不同的结果列

使用 codeigniter 将连接表中的列连接到另一列