我正在努力从数据收集环境的CSV格式数据的“标准化”数据库中提取数据。这将使用PHP / MySQL / JSON完成,目的是绘制数据。我想我有过滤部分,但我需要帮助进行旋转。我们的想法是使用keyNames字段作为数据的过滤器。
以下是查询:
select d.testId,d.rowId,f.keyName,f.keyValue from tests t
inner join data d on t.testId = d.testId
inner join data c on t.testId = c.testId and c.rowId = d.rowId
join data f on f.testId = t.testId and f.rowId = d.rowId
where (d.keyName = 'voltage' and d.keyValue < 5) and (c.keyName = 'temperature' and c.keyValue = 30) and (t.testType = 'testType1');
结果:
+--------+-------+-------------+----------+
| testId | rowId | keyName | keyValue |
+--------+-------+-------------+----------+
| 1 | 1 | voltage | 4 |
| 1 | 1 | temperature | 30 |
| 1 | 1 | velocity | 20 |
| 1 | 2 | voltage | 4 |
| 1 | 2 | temperature | 30 |
| 1 | 2 | velocity | 21 |
| 2 | 1 | voltage | 4 |
| 2 | 1 | temperature | 30 |
| 2 | 1 | velocity | 30 |
| 2 | 2 | voltage | 4 |
| 2 | 2 | temperature | 30 |
| 2 | 2 | velocity | 31 |
+--------+-------+-------------+----------+
我想将其转换为:testId,rowId,voltage,temperature,velocity,例如:
+--------+-------+---------+-------------+----------+
| testId | rowId | voltage | temperature | velocity |
+--------+-------+---------+-------------+----------+
| 1 | 1 | 4 | 30 | 20 |
| 1 | 2 | 4 | 30 | 21 |
| 2 | 1 | 4 | 30 | 30 |
| 2 | 2 | 4 | 30 | 31 |
+--------+-------+---------+-------------+----------+
有什么想法吗?我觉得我很接近这个:
mysql> select f.testId,f.rowId,(if(f.keyName='voltage',f.keyValue,NULL)) as 'voltage',(if(f.keyName='temperature',f.keyValue,NULL)) as 'temperature',(if(f.keyName='velocity',f.keyValue,NULL)) as 'velocity' from tests t inner join data d on t.testId = d.testId inner join data c on t.testId = c.testId and c.rowId = d.rowId join data f on f.testId = t.testId and f.rowId = d.rowId where (d.keyName = 'voltage' and d.keyValue < 5) and (c.keyName = 'temperature' and c.keyValue = 30) and (t.testType = 'testType1');
+--------+-------+---------+-------------+----------+
| testId | rowId | voltage | temperature | velocity |
+--------+-------+---------+-------------+----------+
| 1 | 1 | 4 | NULL | NULL |
| 1 | 1 | NULL | 30 | NULL |
| 1 | 1 | NULL | NULL | 20 |
| 1 | 2 | 4 | NULL | NULL |
| 1 | 2 | NULL | 30 | NULL |
| 1 | 2 | NULL | NULL | 21 |
| 2 | 1 | 4 | NULL | NULL |
| 2 | 1 | NULL | 30 | NULL |
| 2 | 1 | NULL | NULL | 30 |
| 2 | 2 | 4 | NULL | NULL |
| 2 | 2 | NULL | 30 | NULL |
| 2 | 2 | NULL | NULL | 31 |
+--------+-------+---------+-------------+----------+
以下是表定义和数据源供参考:
CREATE TABLE IF NOT EXISTS `data` (
`ptId` int(11) NOT NULL AUTO_INCREMENT,
`testId` int(11) NOT NULL,
`rowId` int(11) NOT NULL,
`keyName` text NOT NULL,
`keyValue` int(11) NOT NULL,
PRIMARY KEY (`ptId`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=33 ;
INSERT INTO `data` (`ptId`, `testId`, `rowId`, `keyName`, `keyValue`) VALUES
(1, 1, 1, 'voltage', 4),
(2, 1, 1, 'temperature', 30),
(3, 1, 1, 'velocity', 20),
(4, 1, 2, 'voltage', 4),
(5, 1, 2, 'temperature', 30),
(6, 1, 2, 'velocity', 21),
(7, 1, 3, 'voltage', 3),
(8, 1, 3, 'temperature', 35),
(9, 1, 3, 'velocity', 22),
(10, 1, 4, 'voltage', 3),
(11, 1, 4, 'temperature', 35),
(12, 1, 4, 'velocity', 23),
(13, 2, 1, 'voltage', 4),
(14, 2, 1, 'temperature', 30),
(15, 2, 1, 'velocity', 30),
(16, 2, 2, 'voltage', 4),
(17, 2, 2, 'temperature', 30),
(18, 2, 2, 'velocity', 31),
(19, 2, 3, 'voltage', 5),
(20, 2, 3, 'temperature', 35),
(21, 2, 3, 'velocity', 32),
(22, 2, 4, 'voltage', 5),
(23, 2, 4, 'temperature', 35),
(24, 2, 4, 'velocity', 33),
(25, 4, 1, 'voltage', 4),
(26, 4, 1, 'velocity', 30),
(27, 4, 2, 'voltage', 4),
(28, 4, 2, 'velocity', 31),
(29, 4, 3, 'voltage', 5),
(30, 4, 3, 'velocity', 32),
(31, 4, 4, 'voltage', 5),
(32, 4, 4, 'velocity', 33);
CREATE TABLE IF NOT EXISTS `tests` (
`testId` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Unique Test ID',
`testType` text NOT NULL,
`startDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`userName` text NOT NULL,
`testSoftware` text NOT NULL,
`comments` text,
`dutID` text,
PRIMARY KEY (`testId`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=8 ;
INSERT INTO `tests` (`testId`, `testType`, `startDate`, `userName`, `testSoftware`, `comments`, `dutID`) VALUES
(1, 'testType1', '2013-03-23 21:06:10', 'testUser1', 'testSoftware1', NULL, 'dut1'),
(2, 'testType1', '2013-03-23 21:10:32', 'testUser1', 'testSoftware1', NULL, 'dut1'),
(3, 'testType1', '2013-03-23 21:10:32', 'testUser1', 'testSoftware1', NULL, 'dut1'),
(4, 'testType2', '2013-03-23 21:10:32', 'testUser1', 'testSoftware1', NULL, 'dut1');
答案 0 :(得分:1)
部分问题是您在SELECT列表中使用了聚合函数,但未使用GROUP BY
。您应该使用与此类似的GROUP BY
:
GROUP BY d.testId, d.rowId
每当您使用聚合函数并且您的选择中有其他列时,它们应该在一个组中。所以你的完整查询应该是:
select d.testId,
d.rowId,
max(if(f.keyName='voltage',f.keyValue,NULL)) as 'voltage',
max(if(f.keyName='temperature',f.keyValue,NULL)) as 'temperature',
max(if(f.keyName='velocity',f.keyValue,NULL)) as 'velocity'
from tests t
inner join data d
on t.testId = d.testId
inner join data c
on t.testId = c.testId
and c.rowId = d.rowId
join data f
on f.testId = t.testId
and f.rowId = d.rowId
where (d.keyName = 'voltage' and d.keyValue < 5)
and (c.keyName = 'temperature' and c.keyValue = 30)
and (t.testType = 'testType1')
GROUP BY d.testId, d.rowId
请注意,虽然您的实际数据结构未在原始问题中显示。看来这可以合并到以下内容:
select d.testid,
d.rowid,
max(case when d.keyName = 'voltage' and d.keyValue < 5 then d.keyValue end) voltage,
max(case when d.keyName = 'temperature' and d.keyValue =30 then d.keyValue end) temperature,
max(case when d.keyName = 'velocity' then d.keyValue end) velocity
from tests t
left join data d
on t.testid = d.testid
group by d.testid, d.rowid
见SQL Fiddle with Demo。这给结果只有一个data
表的连接:
| TESTID | ROWID | VOLTAGE | TEMPERATURE | VELOCITY |
-----------------------------------------------------
| 1 | 1 | 4 | 30 | 20 |
| 1 | 2 | 4 | 30 | 21 |
| 2 | 1 | 4 | 30 | 30 |
| 2 | 2 | 4 | 30 | 31 |