MySQL中具有可变动态列数的透视表(组键=id字段的值行)

MySQL中具有可变动态列数的透视表(组键=id字段的值行),mysql,dynamic,pivot,Mysql,Dynamic,Pivot,虽然有很多关于数据透视表的问题,但似乎没有一个能解决我需要做的事情,或者看起来太复杂,我无法开始工作 我有一个应用程序可以通过无线网络从远程远程远程通信设备收集数据,例如运行各种嵌入式数据收集应用程序的GSM调制解调器。我的数据库将每组数据与调制解调器ID相关联。收集的参数很多,大约有100种不同的类型,因此为每个调制解调器创建一个包含100列的表似乎不太实际,特别是因为不同的调制解调器应用程序可能只使用可能的100个参数中的10个。因此,我有一个非常简单的“参数”表,其中包含“modem_id

虽然有很多关于数据透视表的问题,但似乎没有一个能解决我需要做的事情,或者看起来太复杂,我无法开始工作

我有一个应用程序可以通过无线网络从远程远程远程通信设备收集数据,例如运行各种嵌入式数据收集应用程序的GSM调制解调器。我的数据库将每组数据与调制解调器ID相关联。收集的参数很多,大约有100种不同的类型,因此为每个调制解调器创建一个包含100列的表似乎不太实际,特别是因为不同的调制解调器应用程序可能只使用可能的100个参数中的10个。因此,我有一个非常简单的“参数”表,其中包含“modem_id”、“parm_id”和“value”字段,即经典的key=value表

我想写一个简单的SQL查询,它允许我搜索特定的调制解调器,对特定的parm_id进行排序,并使用limit和offset对结果进行分页

表参数中某些行的示例:

我想按调制解调器id将上述内容分组到一个临时表中,其中parm_id在单独的列中,例如:

modem_id | parm_id1 | parm_id4 | parm_id9
100 '11.1' '22.2' '3.33'
102 '12.3' '23.4' '3.45'

这看起来应该很简单,而且是一件很普通的事情,但我见过的唯一解决方案涉及几十行代码,准备好的语句,还有奇怪的转义序列,到处都是引号字符,这让我甚至无法理解查询应该做什么,也无法在本例中使用这些字符。

下面的查询将为您提供所需的结果

 select  modem_id, 
 IF(parm_id = 1, value, NULL) as parm_id1,
 IF(parm_id = 2, value, NULL) as parm_id2,
 ......
 IF(parm_id = 100, value, NULL) as parm_id100,
  from table

希望有帮助。

你没有约会吗?每个调制解调器的每个参数都有一个值?是否需要聚合任何参数值?@geoandri是的,每个调制解调器id、parm\U id组合只有一个值。参数表中还有一个timestamp字段,但不需要包含在解决方案中,因为它通常不用于顶级查询,如果需要,可以单独检索,我希望问题尽可能简单。我不需要聚合任何值。这看起来应该可以很好地工作,实际上对于<~20个parm_id来说可能不会太长,并且很容易在PHP中生成。将在第二天或第二天进行测试,然后用结果更新此注释。Thanks@davidg“在PHP中生成”????如果您使用的是PHP,就不用担心pivot了。使用loop@Strawberry是的,对于小数据集,使用PHP会容易得多,到目前为止,我一直在这样做。但是数据库越来越大,有数千个调制解调器,可能在1-2年内达到10000个,我希望现在能够用SQL对结果进行排序和分页,而不必将超过100K行的数据读入PHP,这将增加服务器带宽并降低性能。同样,这似乎是一件很常见的事情,即将调制解调器和参数表之间的1:n关系转换为更像1:1的关系,我很惊讶在MySQL中没有一种简单的方法可以做到这一点。@geoandri这是一种简单的方法,可以“透视”表,但是,它有一个主要的性能限制,即它对于仅填充实际数据集中存在的列不是动态的。e、 例如,在我的示例中,数据集中只有parm_id的1、4和9,因此我不希望查询填充100列,而在这种情况下它应该只填充3列。如果您能想出一个更优化的解决方案,只填充数据集中的列,请告诉我。Thanks@DavidG我认为,如果您不知道要填充哪些参数,下面的链接将对您有所帮助
 select  modem_id, 
 IF(parm_id = 1, value, NULL) as parm_id1,
 IF(parm_id = 2, value, NULL) as parm_id2,
 ......
 IF(parm_id = 100, value, NULL) as parm_id100,
  from table