Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.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中的数据从3维到2维?_Mysql - Fatal编程技术网

什么';这是正确的方法;“展平”;mySQL中的数据从3维到2维?

什么';这是正确的方法;“展平”;mySQL中的数据从3维到2维?,mysql,Mysql,我有三张桌子 标签 用户值 用户 标签如下所示: 1|First Name 2|Last Name 3|Favorite Book etc... 1|[phone_number] 2|[phone_number] etc.... 1| [label_id_for_First_Name] |John | [user_id] 2| [label_id_for_Last_Name] |Smith | [user_id] 3| [label_id_for_Fav_B

我有三张桌子

标签

用户值

用户

标签如下所示:

1|First Name
2|Last Name
3|Favorite Book
etc...
1|[phone_number]
2|[phone_number]
etc....
1|  [label_id_for_First_Name]  |John      |  [user_id]
2|  [label_id_for_Last_Name]   |Smith     |  [user_id]
3|  [label_id_for_Fav_Book]    |Moby Dick |  [user_id]
etc...
用户看起来像这样:

1|First Name
2|Last Name
3|Favorite Book
etc...
1|[phone_number]
2|[phone_number]
etc....
1|  [label_id_for_First_Name]  |John      |  [user_id]
2|  [label_id_for_Last_Name]   |Smith     |  [user_id]
3|  [label_id_for_Fav_Book]    |Moby Dick |  [user_id]
etc...
UserValues如下所示:

1|First Name
2|Last Name
3|Favorite Book
etc...
1|[phone_number]
2|[phone_number]
etc....
1|  [label_id_for_First_Name]  |John      |  [user_id]
2|  [label_id_for_Last_Name]   |Smith     |  [user_id]
3|  [label_id_for_Fav_Book]    |Moby Dick |  [user_id]
etc...
某些用户可能没有填写某些字段(除用作主键的电话号码外,所有字段都是可选的)

我很难理解如何编写一个查询,将这些数据展平为:

uid      |First_Name|Last_Name | Favorite_Book
[user_id]|John      |Smith     | Moby Dick //user has all fields filled in
[user_id]|Mary      | [null]   | Kite Runner //user didn't have a last name
其想法是,它将增加与这些特定用户关联的标签数量相同的列的列宽

我想在用户上选择,每个用户有一行,所有值都在右边

我可以在几个查询中看到我是如何做到这一点的,但我希望知道正确的方法是什么(也许是在几个查询中做到这一点,但我怀疑不是这样)


TIA。

如果您想使用当前数据编写查询,并在示例中给出结果,则可以:

SQL编码错误

SELECT 
  u.id as user_id
  , uvfirstname.value as firstname
  , uvlast_name.value as lastname
  , uvbook.value as book
FROM users u
LEFT JOIN uservalues uvfirstname 
       ON (uvfirstname.label_id =
             (SELECT l1.id FROM label l1 WHERE l1.name = 'First name')
           AND uvfirstname.user_id = u.id)
LEFT JOIN uservalues uvlastname 
       ON (uvlastname.label_id = 
             (SELECT l2.id FROM label l2 WHERE l2.name = 'Last name')
           AND uvlastname.user_id = u.id)
LEFT JOIN uservalues uvbook
       ON (uvbook.label_id = 
             (SELECT l3.id FROM label l3 WHERE l3.name = 'Fav book')
           AND uvbook.user_id = u.id)

如果您想使用当前数据编写查询,并在示例中给出结果,可以这样做:

SQL编码错误

SELECT 
  u.id as user_id
  , uvfirstname.value as firstname
  , uvlast_name.value as lastname
  , uvbook.value as book
FROM users u
LEFT JOIN uservalues uvfirstname 
       ON (uvfirstname.label_id =
             (SELECT l1.id FROM label l1 WHERE l1.name = 'First name')
           AND uvfirstname.user_id = u.id)
LEFT JOIN uservalues uvlastname 
       ON (uvlastname.label_id = 
             (SELECT l2.id FROM label l2 WHERE l2.name = 'Last name')
           AND uvlastname.user_id = u.id)
LEFT JOIN uservalues uvbook
       ON (uvbook.label_id = 
             (SELECT l3.id FROM label l3 WHERE l3.name = 'Fav book')
           AND uvbook.user_id = u.id)

查看EAV模式(google it)。如果您的列是已知的和常规的,为什么不将它们包含在表中,而不是单独的值表中?如果您的列未知,您如何期望在不选择所需列的情况下动态获得合理的表视图:难道不能有数千列吗?@Dr.Dredel如果这些是不同的用户组(或类),而不是随机的不同字段,我会像这样对其进行规范化:1。标准列(名字、姓氏)在users表中直接显示。2.将诸如“收藏夹”之类的额外字段拆分为一个user\u book\u fields表,该表引用具有user\u id外键的用户。3.为用户提供一个类型列,以便您知道要针对该列加入哪些用户x字段表。正如您所承认的,所有用户类型的连接都是不合理的,因为您会有1000列。@Dani,EAV是一种反模式的连接,它会使您的数据库速度变慢。电话号码会导致坏的PK,我总是填写06-12345678作为电话号码。请查看EAV模式(谷歌it)。如果您的列是已知的和常规的,为什么不将它们包括在表中,而不是一个单独的值表?如果您的列未知,您如何期望在不选择所需列的情况下动态获得合理的表视图:难道不能有数千列吗?@Dr.Dredel如果这些是不同的用户组(或类),而不是随机的不同字段,我会像这样对其进行规范化:1。标准列(名字、姓氏)在users表中直接显示。2.将诸如“收藏夹”之类的额外字段拆分为一个user\u book\u fields表,该表引用具有user\u id外键的用户。3.为用户提供一个类型列,以便您知道要针对该列加入哪些用户x字段表。正如您所承认的,所有用户类型的连接都是不合理的,因为您将有1000列。@Dani,EAV是一种反模式的连接,它会使您的数据库速度变慢。电话号码会导致坏的PK,我总是填写06-12345678作为电话号码。