首页 > 解决方案 > mysql 从基于具有相似内容的字段分组在一起的表中选择字段

问题描述

好的,这是我在这里的第一篇文章,我真的很难掌握这个网站的运作方式。所以我现在正在编辑我原来的问题,希望这次我能做对。请请原谅我,我又搞砸了。-2 评级,非常感谢。此外,英语与我的母语相差甚远,所以我很难解释我的意思。

原始问题

我有一个似乎无法解决的sql-thingy。虽然看起来很简单。也许以前有人问过,但我不知道如何总结它小到足以问谷歌。不过我确实试过了(这个标题)

我需要一个 3d 表,其中每个字段都有多个属性。我的表格有点像这样(小例子) id, element, content, lang, groupid groupid 是将字段组保持在一起的原因。

例子

| 编号 | 元素 | 内容 | 朗 | 群号
| 1 | 名字 | 约翰 | zh | 1
| 2 | 姓氏 | 约翰逊 | zh | 1
| 3 | 电话 | 12345 | zh | 1
| 4 | 邮政编码 | 12345 | zh | 1
| 5 | 名字 | 皮特 | 荷兰 | 2
| 6 | 姓氏 | 彼得斯 | 荷兰 | 2
| 7 | 电话 | 23456 | 荷兰 | 2
| 8 | 邮政编码 | 1234AA | 荷兰 | 2

到目前为止,这种布局很适合我需要它。但现在我需要以这种方式选择记录

| 组ID | 名字 | 姓氏 | 电话 | 邮政编码
| 1 | 约翰 | 约翰逊 | 12345 | 12345
| 2 | 皮特 | 彼得斯 | 23456 | 1234AA

或者换一种说法,我需要一个看起来像这样的结果数组

$arr(
"0" => Array("groupid" =>"1","firstname"=>"John","lastname"=>"Johnson","telnr"=>"12345","zipcode"=>"12345"),
"1" => Array("groupid" =>"2","firstname"=>"Piet","lastname"=>"Pieters","telnr"=>"23456","zipcode"=>"1234AA"),
)

如果我能在单个 sql 查询中完成这将是最好的。但我不介意使用更简单的查询并让 php 完成其余的工作。它看起来很简单,所以我想这只是一个盲点。但还是

--- 编辑和更新 ---

到目前为止,我已经能够使用一点 php 来解决我的问题,方法是在遍历查询结果的同时构建一个新数组。像这样:

foreach($row as $item) {
$newarr[$item['groupid']]["id"] = $item['groupid'];
$newarr[$item['groupid']][$item['element'] = $item['groupid'];
}

$newarr 正是我所需要的,但我更喜欢 sql 解决方案。

我尝试这个困难的解决方案的原因是我需要很多额外的信息,不是每个记录,而是每个字段。这在我正在构建的 CMS 中是必需的。这个想法是在适当的表单元素中获得一定的价值。

就像“姓氏”会自动放置在 input:type=text 标记内。这很好用,当我尝试使用列类型作为来源来决定我将使用的表单元素时。

但是当我使用 columntype text 时遇到了一个问题,因为有时它应该指向一个 textarea,有时它应该指向一个更改为 ckeditor 窗口的 textarea。仅列类型是不够的。

除此之外,我在每一列上都使用了更多信息。像语言(它用于双语项目)。还有editdate...

标签: phpmysql

解决方案


处理 EAV 时的一种标准方法如下,但如果属性是广泛的和/或动态的,那么在应用程序代码中处理逻辑可能会更好:

DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table
(id SERIAL PRIMARY KEY
,entity INT NOT NULL
,attribute VARCHAR(12) NOT NULL
,value VARCHAR(12) NOT NULL
,lang CHAR(2) NOT NULL
,UNIQUE(entity,attribute)
);

INSERT INTO my_table VALUES
(1,1,'firstname','John','en'),
(2,1,'lastname','Johnson','en'),
(3,1,'telnr','12345','en'),
(4,1,'zipcode','12345','en'),
(5,2,'firstname','Piet','nl'),
(6,2,'lastname','Pieters','nl'),
(7,2,'telnr','23456','nl'),
(8,2,'zipcode','1234AA','nl');

SELECT entity
     , MAX(CASE WHEN attribute = 'firstname' THEN value END) firstname
     , MAX(CASE WHEN attribute = 'lastname' THEN value END) lastname
     , MAX(CASE WHEN attribute = 'telnr' THEN value END) telnr
     , MAX(CASE WHEN attribute = 'zipcode' THEN value END) zipcode
  FROM my_table 
 GROUP 
    BY entity;

+--------+-----------+----------+-------+---------+
| entity | firstname | lastname | telnr | zipcode |
+--------+-----------+----------+-------+---------+
|      1 | John      | Johnson  | 12345 | 12345   |
|      2 | Piet      | Pieters  | 23456 | 1234AA  |
+--------+-----------+----------+-------+---------+

推荐阅读