31

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

人们

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

返回属性之一和总属性计数也是可以接受的。

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

有什么办法吗?

4

3 回答 3

30

采用:

   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 (文档) 以返回 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,作为每个用户的唯一值,将是一个更好的选择。

于 2010-05-23T18:09:34.950 回答
4

您可以使用INNER JOIN将两个表链接在一起。有关 JOIN 的更多信息

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

但是,向此类表添加唯一主键并创建索引以提高速度通常要快得多。

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

然后查询看起来像这样:

SELECT *
FROM People P
INNER JOIN Properties Pr
  ON Pr.id = P.peopleId
WHERE P.Name = 'Joe'
于 2010-05-23T18:11:23.383 回答
4
SELECT x.name,(select GROUP_CONCAT(y.Properties SEPARATOR ', ')
FROM PROPERTIES y 
WHERE y.name.=x.name ) as Properties FROM mst_People x 

试试这个

于 2015-05-05T09:24:54.193 回答