1

我正在努力从用于数据收集环境的 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');
4

1 回答 1

1

您的部分问题是您在 SELECT 列表中使用聚合函数,但您没有使用GROUP BY. 您应该使用GROUP BY与此类似的:

GROUP BY d.testId, d.rowId

每当您使用聚合函数并且您的选择中有其他列时,它们应该在 group by 中。所以你的完整查询应该是:

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 |
于 2013-03-24T21:51:44.920 回答