Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 不使用GroupConcat将多行合并为一行_Mysql_Join_Row - Fatal编程技术网

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您已经回答了,无论如何,感谢您的快速响应