Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/61.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 选择包含元数据的行_Mysql_Sql - Fatal编程技术网

Mysql 选择包含元数据的行

Mysql 选择包含元数据的行,mysql,sql,Mysql,Sql,我有两张桌子 表1 =================================== = Id = Name = email = =================================== = 1 = David = d@d.com = =================================== 表2 ================================== = uid = key =

我有两张桌子

表1

===================================
= Id = Name             =  email  =
===================================
= 1  = David            = d@d.com =
===================================
表2

==================================
= uid = key        =  Value      =
==================================
= 1   = Age        =  18         =
= 1   = Tele       =  0123456798 =
==================================
其思想是UID与Id关联以链接表

我想做的是运行一个SQL查询以获得以下输出

=========================================================================
= Id = Name             =  email  = age        =  Tele                  =
=========================================================================
= 1  = David            = d@d.com = 18         = 012345678              =
=========================================================================
我需要运行什么查询

谢谢诸如此类的东西:

select 
  t.Id,
  t.Name, 
  t.Email,
  (select Value from Table2 t2 where t2.uid = t.Id and t2.Key = 'Age') as Age, 
  (select Value from Table2 t2 where t2.uid = t.Id and t2.Key = 'Tele') as Tele 

from Table1 t
如果您事先知道密钥,则上述查询将起作用。 It名称未知从数据库获取可用密钥名称的列表:

select distinct Key from Table2
大概是这样的:

select 
  t.Id,
  t.Name, 
  t.Email,
  (select Value from Table2 t2 where t2.uid = t.Id and t2.Key = 'Age') as Age, 
  (select Value from Table2 t2 where t2.uid = t.Id and t2.Key = 'Tele') as Tele 

from Table1 t
如果您事先知道密钥,则上述查询将起作用。 It名称未知从数据库获取可用密钥名称的列表:

select distinct Key from Table2
我简单地连接了表2好几次(好像它是几个表),每次只取与某个键匹配的值。然后,对于我感兴趣的值,我只需为每个值选择适当的别名,并相应地命名列


我简单地连接了表2好几次(好像它是几个表),每次只取与某个键匹配的值。然后,对于我感兴趣的值,我只需为每个值选择适当的别名,并相应地命名列

虽然您已经接受了答案,但我发布此消息是为了提供另一种解决方案。您正试图
PIVOT
数据,而MySQL没有PIVOT函数,因此您可以将聚合函数与
CASE
语句一起使用

如果有已知数量的值,则可以对查询进行硬编码:

select t1.id,
    t1.name,
    t1.email,
    MAX(CASE WHEN t2.key='age' THEN t2.value ELSE NULL END) AS age,
    MAX(CASE WHEN t2.key='tele' THEN t2.value ELSE NULL END) AS tele
FROM Table1 t1 
LEFT JOIN Table2 t2 
  ON t1.Id = t2.uid
GROUP BY t1.id, t1.name, t1.email

但是,如果您有未知数量的
值,则需要使用准备好的语句来创建动态sql版本:

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'max(case when t2.`key` = ''',
      `key`,
      ''' then t2.Value else null end) AS ',
      `key`
    )
  ) INTO @sql
FROM table2;

SET @sql = CONCAT('SELECT t1.id, t1.name, t1.email, ', @sql, ' 
                  FROM table1 t1
                  left join table2 t2
                    on t1.id = t2.uid
                  GROUP BY t1.id, t1.name, t1.email');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

结果:

| ID |  NAME |   EMAIL | AGE |      TELE |
------------------------------------------
|  1 | David | d@d.com |  18 | 123456798 |

两者都会产生相同的结果,但准备好的语句版本会在运行时生成
值的列表。

当您已经接受答案时,我将发布此消息以提供替代解决方案。您正试图
PIVOT
数据,而MySQL没有PIVOT函数,因此您可以将聚合函数与
CASE
语句一起使用

如果有已知数量的值,则可以对查询进行硬编码:

select t1.id,
    t1.name,
    t1.email,
    MAX(CASE WHEN t2.key='age' THEN t2.value ELSE NULL END) AS age,
    MAX(CASE WHEN t2.key='tele' THEN t2.value ELSE NULL END) AS tele
FROM Table1 t1 
LEFT JOIN Table2 t2 
  ON t1.Id = t2.uid
GROUP BY t1.id, t1.name, t1.email

但是,如果您有未知数量的
值,则需要使用准备好的语句来创建动态sql版本:

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'max(case when t2.`key` = ''',
      `key`,
      ''' then t2.Value else null end) AS ',
      `key`
    )
  ) INTO @sql
FROM table2;

SET @sql = CONCAT('SELECT t1.id, t1.name, t1.email, ', @sql, ' 
                  FROM table1 t1
                  left join table2 t2
                    on t1.id = t2.uid
                  GROUP BY t1.id, t1.name, t1.email');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

结果:

| ID |  NAME |   EMAIL | AGE |      TELE |
------------------------------------------
|  1 | David | d@d.com |  18 | 123456798 |

两者都会产生相同的结果,但准备好的语句版本会在运行时生成
key
值的列表。

您不需要像表1中那样在case语句中使用电子邮件,也不需要像表1中那样在case语句中使用电子邮件hanks-愚蠢的问题是,在不知道密钥在表中的情况下,是否有这样做的必要表。我能想到的最好办法是编写代码,在给定键名的情况下自动生成查询。好的,谢谢。每个人都很乐于助人。我不太懂SQL。在我的MySQL版本(5.0)中,“Age=”和“Tele=”出现错误,我必须使用“as Age”和“as Tele”。谢谢-愚蠢的问题是,在不知道表中有哪些键的情况下这样做。我能想到的最好办法是编写代码,在给定键名的情况下自动生成查询。好的,谢谢。每个人都很乐于助人。我不太懂SQL。在我的MySQL版本(5.0)中,“Age=”和“Tele=”出现错误,我必须使用“as Age”和“as Tele”。是否只有两个键值可以转换为列?或者你会有一个未知的数字吗?未知的值的数字你会只有两个键值转换成列吗?或者你会有一个未知的数字吗?未知的数值一点解释你的解决方案为什么有效会改善这个答案。一点解释你的解决方案为什么有效会改善这个答案。很好的解决方案。我特别喜欢在查询中构建语句,其中所有内容都可用。我试着用一个包含键值的group_concat()列表和一个很难处理的替换来完成它。这是一个很好的解决方案。我特别喜欢在查询中构建语句,其中所有内容都可用。我试图用一个包含键值的group_concat()列表和一个很难处理的替换来完成它。