Mysql 不使用GroupConcat将多行合并为一行
如何在没有组连接的情况下将多行连接到一行 假设我有如下表格:Mysql 不使用GroupConcat将多行合并为一行,mysql,join,row,Mysql,Join,Row,如何在没有组连接的情况下将多行连接到一行 假设我有如下表格: 表用户: uid | name ----------- 1 | A 2 | B 表元: uid | metaid | metaval ------------------------ 1 | 1 | Jsep St. 1 | 2 | St. Oak No. 15 2 | 1 | Dt. San Joseph 2 | 2 | St. Oak No. 17 2
表用户:
uid | name
-----------
1 | A
2 | B
表元:
uid | metaid | metaval
------------------------
1 | 1 | Jsep St.
1 | 2 | St. Oak No. 15
2 | 1 | Dt. San Joseph
2 | 2 | St. Oak No. 17
2 | 3 | OA.
表元属性:
metaid | metakey
-----------------
1 | school
2 | address
3 | dept
4 | acc
我想选择一个带有学校和地址的用户,以便查询
SELECT
uid, name, metaval
FROM user
INNER JOIN meta ON meta.uid = user.uid
WHERE meta.metaid = 1 OR meta.metaid = 2
它将输出
| UID | Name | MetaVal |
--------------------------------
| 1 | A | Jsep St. |
| 1 | A | St. Oak No. 15 |
我想要的结果是这样的
uid | name | school | address
-------------------------------------
1 | A | Jsep St.| St. Oak No. 15
对于组concat,值为“school”和“address”的元属性不在不同的列中,而是一列
我试着加入两次,效果不错,但我觉得这并不优雅
SELECT
uid, name, T1.metaval as school, T2.metaval as address
FROM user
INNER JOIN meta T1 ON T1.uid = user.uid AND T1.metaid = 1
INNER JOIN meta T2 ON T2.uid = user.uid AND T2.metaid = 2
有更好的解决办法吗
有更好的解决办法吗
简短回答
没有
中等长度答案
您的查询存在一些问题
- 您忘记包含
表用户
- 格式化SQL以使其易于阅读
- 如果某些数据可能丢失,请考虑使用
LEFT JOIN
SELECT uid, name, T1.metaval AS school, T2.metaval AS address
FROM user
LEFT JOIN meta T1 ON T1.uid = user.uid AND T1.metaid = 1
LEFT JOIN meta T2 ON T2.uid = user.uid AND T2.metaid = 2
长答案
是的,这个查询很难看,但问题不在于查询,而在于数据库设计。您正在使用的设计称为(EAV)。尽可能避免使用EAV设计!无论何时使用EAV,所有查询都会变成多个连接怪物。如果可以将每个值存储在同一行中的单独列中,则会容易得多
当然,在某些情况下,您必须使用EAV。然后你只需要接受你的查询会很长,很难阅读,不雅观,而且很慢。这就是您为拥有灵活的模式所做的权衡
有更好的解决办法吗
简短回答
没有
中等长度答案
您的查询存在一些问题
- 您忘记包含
表用户
- 格式化SQL以使其易于阅读
- 如果某些数据可能丢失,请考虑使用
LEFT JOIN
SELECT uid, name, T1.metaval AS school, T2.metaval AS address
FROM user
LEFT JOIN meta T1 ON T1.uid = user.uid AND T1.metaid = 1
LEFT JOIN meta T2 ON T2.uid = user.uid AND T2.metaid = 2
长答案
是的,这个查询很难看,但问题不在于查询,而在于数据库设计。您正在使用的设计称为(EAV)。尽可能避免使用EAV设计!无论何时使用EAV,所有查询都会变成多个连接怪物。如果可以将每个值存储在同一行中的单独列中,则会容易得多
当然,在某些情况下,您必须使用EAV。然后你只需要接受你的查询会很长,很难阅读,不雅观,而且很慢。这就是您在使用灵活模式时所做的权衡。也许这是一个简短的答案:
SELECT uid, name,
max( case when meta.metaid = 1 then metaval else '' end ) as school,
max( case when meta.metaid = 2 then metaval else '' end ) as address
FROM user
INNER JOIN meta
ON meta.uid = user.uid
WHERE meta.metaid = 1 OR meta.metaid = 2
group by uid, name
也许这是一个简短的回答:
SELECT uid, name,
max( case when meta.metaid = 1 then metaval else '' end ) as school,
max( case when meta.metaid = 2 then metaval else '' end ) as address
FROM user
INNER JOIN meta
ON meta.uid = user.uid
WHERE meta.metaid = 1 OR meta.metaid = 2
group by uid, name
你如何在
1 | A | Jsep St.| St.Oak No.15
和1 | A | St.Oak No.15 | Jsep St.
之间做出决定?学校是id=1的元,地址是id=2的元你的双连接是正确的方法。@MarkByers你已经回答过了,无论如何,感谢您的快速响应。您如何在1 | A | Jsep St.| St.Oak No.15
和1 | A | St.Oak No.15 | Jsep St.
之间做出决定?学校是id=1的元,地址是id=2的元。您的双连接是正确的方式。@MarkByers您已经回答了,无论如何,感谢您的快速响应