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

Gho*_*der 22 mysql sql database join group-concat

我有一个表到实体(让我们称之为人)和属性(一个人可以有任意数量的属性).例如:

Name  Age
--------
Jane  27
Joe   36
Jim   16
Run Code Online (Sandbox Code Playgroud)

属性

Name   Property
-----------------
Jane   Smart
Jane   Funny
Jane   Good-looking
Joe    Smart
Joe    Workaholic
Jim    Funny
Jim    Young
Run Code Online (Sandbox Code Playgroud)

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

Ex: People older than 26
Name Properties
Jane Smart, Funny, Good-looking
Joe Smart, Workaholic
Run Code Online (Sandbox Code Playgroud)

返回其中一个属性和总属性数也是可以接受的.

查询应该是高效的:人员表中有数百万行,属性表中有数十万行(因此大多数人没有属性).一次选择数百行.

有什么办法吗?

OMG*_*ies 25

使用:

   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
Run Code Online (Sandbox Code Playgroud)

您需要MySQL函数GROUP_CONCAT(文档)以返回以逗号分隔的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
Run Code Online (Sandbox Code Playgroud)

我意识到这是一个例子,但当你考虑有多少"约翰史密斯"时,使用名字是参考完整性的一个不好的选择.分配user_id是一个数值,是一个更好的选择.

  • 如果有人遇到这个问题而且正在使用Oracle DB,那么就有一个等效的LISTAGG函数(因为我认为是Oracel 11.2):http://docs.oracle.com/cd/E14072_01/server.112/e10592/functions087.htm (3认同)
  • @OMGPonies是的,我知道这一点。不要试图回答这个问题,只要对在Oracle DB上进行类似查询的任何人提供帮助。 (2认同)