我有一个表到实体(让我们称之为人)和属性(一个人可以有任意数量的属性)。例如:
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
返回其中一个属性和总属性数也是可以接受的。
查询应该是高效的:人员表中有数百万行,属性表中有数十万行(因此大多数人没有属性)。一次选择数百行。
有什么办法吗?
答案 0 :(得分:23)
使用:
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
我意识到这是一个例子,但是当你考虑有多少“约翰史密斯”时,使用名字对于参考完整性来说是一个糟糕的选择。分配user_id(数值)将是更好的选择。
答案 1 :(得分:4)
SELECT x.name,(select GROUP_CONCAT(y.Properties SEPARATOR ', ')
FROM PROPERTIES y
WHERE y.name.=x.name ) as Properties FROM mst_People x
试试这个
答案 2 :(得分:3)
您可以使用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'