2013-03-24 67 views
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,电压,温度,速度,如:

+--------+-------+---------+-------------+----------+ 
| 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'); 
+1

您付多少钱? – Jocelyn 2013-03-24 01:02:35

+0

这不适用于付费应用程序。该评论如何有用? – jdhar 2013-03-24 02:55:13

+1

这里似乎没有问题,只是你想要达到的目标列表。请问一个具体的问题,我相信你会得到一个很好的,有用的答案。 – vascowhite 2013-03-24 19:47:19

回答

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 | 
+0

非常有帮助,谢谢!看起来像group by是失踪的关键。我试过你的优化,我不认为它执行逻辑和我需要。我正在尝试您的原始解决方案,看看我是否正确理解它,并且它适合我的需求。我已更新原始文章以包含数据结构和样本数据。 – jdhar 2013-03-25 00:47:18

+0

@jdhar根据您提供的样本数据,您希望得到的结果是什么? – Taryn 2013-03-25 01:31:31

+0

我已经包含了您的第一个查询获得的所需输出。我们的想法是使用keyName与keyField比较的任意组合来过滤数据(我给出的例子是温度= 30,电压<5)。所以它看起来像添加字段,我只是复制内部联接块。 – jdhar 2013-03-25 01:55:12

相关问题