这个问题似乎很通用,但它相当复杂。
让我们从软件的基础知识开始:
MS Access 2016
MS SQL ver。 17.7
DAQFactory 17.1
DAQFactory是一款SCADA软件,我用它来测量和存储来自多个温度传感器的数据。我使用“导出集”将传感器数据导出到我的MSSQL数据库。我每分钟对传感器数据进行一次采样,生成1行传感器数据。我已经设置好为每个样本创建一个新表(因为我只需要采样10次/ 1到10分钟,这样我就不需要一直更改表的名称)。
我有6个温度传感器,DAQFactory以这样的格式导出:
MS SQL数据库只是我的数据从DAQFactory到MS Access的载体/通道,因此我对数据库没有任何问题。
这是一个学校项目,我在脑海里。我正在制作软件包的客户想要在包含其他类型数据的报告中收集他的数据。因此,我需要将传感器数据放入如下形式:
我使用MS Access创建报告并从我的数据库中收集数据。我已经尝试了几种类型的查询,但我不能让它像我想的那样工作。
问题是数据库和报表中的表具有相反的行和列位置,我无法在Access(也称为转置)的查询中切换它。
我看过其中一些解决方案:
https://access-programmers.co.uk/forums/showthread.php?t=169794
converting column names to use as row fields in Access
Access - transpose some column data into row records
加入功能
PIVOT功能
但我无法让它发挥作用。
导出集:
我的所有导出集都包含相同的列:
[TheTime],
[T_01],
[T_02],
[T_03],
[T_04],
[T_05],
[T_06]
导出集称为:
dbo.Temp_1min
dbo.Temp_2min
dbo.Temp_3min
dbo.Temp_4min
等等达到10个。
将其导入Access时,[TheTime]成为主键,所有记录的样本都记录在完全相同的秒上,因此这自然就是表的ID。
这是我用来显示数据的代码。我正在使用“Totals:Last”,因此我表中唯一显示的是每个表和传感器的最后一个值。请原谅代码,它的格式为挪威语,但唯一的区别是“SisteAv”,意思是“LastOf”,例如“Totals:Last”函数。
从“dbo_Temp_1min”表中获取最后一个值的代码,此查询称为“Temp_Samples1”:
SELECT Last(dbo_Temp_1min.TheTime) AS SisteAvTheTime, Last(dbo_Temp_1min.T_01) AS SisteAvT_01, Last(dbo_Temp_1min.T_02) AS SisteAvT_02, Last(dbo_Temp_1min.T_03) AS SisteAvT_03, Last(dbo_Temp_1min.T_04) AS SisteAvT_04, Last(dbo_Temp_1min.T_05) AS SisteAvT_05, Last(dbo_Temp_1min.T_06) AS SisteAvT_06
FROM dbo_Temp_1min;
将多个表合并为一个代码的代码:
SELECT [SisteAvTheTime], [SisteAvT_01], [SisteAvT_02], [SisteAvT_03], [SisteAvT_04], [SisteAvT_05], [SisteAvT_06]
FROM Temp_Samples1
UNION
SELECT [SisteAvTheTime], [SisteAvT_01], [SisteAvT_02], [SisteAvT_03], [SisteAvT_04], [SisteAvT_05], [SisteAvT_06]
FROM Temp_Samples2;
这是我得到的当前结果,列和行与我需要的相反:
澄清我的需要:
1)第一列列出所有温度传感器的名称(T_01,T_02,T_03等)。
2)第二列列出表1中的最后一行传感器数据(dbo.Temp_1min)。
3)列出表2中最后一行传感器数据的第三列(dbo.Temp_2min)
4)列出表3中最后一行传感器数据的第四列(dbo.Temp_3min)
等等......“TheTime”列与最终结果无关,应隐藏,因为时间取决于表格上的名称(1分钟,2分钟,3分钟等)
根据请求,[dbo.Temp_1min]的MS SQL数据库中包含的数据:
TheTime T_01 T_02 T_03 T_04 T_05 T_06
----------------------- ------------- ------------- ------------- ------------- ------------- -------------
2018-05-24 15:18:37.000 -0,080911 -0,051013 0,090363 0,034291 -0,096702 -0,016438
2018-05-25 15:04:22.010 0,095227 0,021559 -0,099226 -0,003178 0,099815 -0,015269
2018-05-25 15:04:23.003 0,095226 0,021562 -0,099226 -0,003181 0,099815 -0,015265
2018-05-25 20:06:17.000 0,061521 0,072766 -0,075043 -0,058863 0,085937 0,042978
2018-05-25 20:12:47.000 60,50084 73,64336 -74,18618 -59,89857 85,27211 44,13688
2018-05-25 20:12:47.000 60,50084 73,66345 -74,16626 -59,92236 85,25659 44,16353
2018-05-25 20:06:17.000 0,061521 0,072787 -0,075024 -0,058887 0,085922 0,043005
2018-05-25 20:10:40.003 60,83407 73,37933 -74,46661 -59,5624 85,49031 43,7604
2018-05-25 20:10:40.003 60,83407 73,37933 -74,44677 -59,58627 85,47488 43,78712
2018-05-25 20:23:07.003 58,85883 75,03191 -72,77819 -61,54791 84,16943 45,98995
(受影响的10行)
答案 0 :(得分:0)
UNION查询限制为50条SELECT行。你有10个表和6个传感器,这意味着60个SELECT行。如果两者都较少,则单个UNION可以合并表,然后CROSSTAB可以转动数据。相反,执行10次UNION查询并加入它们。这是第一个UNION的例子。
SELECT TOP 1 TheTime, T_01 AS Min1, "T01" AS Sensor, "1Min" AS Source FROM Temp_1min ORDER BY TheTime DESC
UNION (SELECT TOP 1 TheTime, T_02, "T02", "1Min" FROM Temp_1min ORDER BY TheTime DESC)
UNION (SELECT TOP 1 TheTime, T_03, "T03", "1Min" FROM Temp_1min ORDER BY TheTime DESC)
UNION (SELECT TOP 1 TheTime, T_04, "T04", "1Min" FROM Temp_1min ORDER BY TheTime DESC)
UNION (SELECT TOP 1 TheTime, T_05, "T05", "1Min" FROM Temp_1min ORDER BY TheTime DESC)
UNION (SELECT TOP 1 TheTime, T_06, "T06", "1Min" FROM Temp_1min ORDER BY TheTime DESC);
现在选择其中一个查询作为' master'并将其他9加入其中。这是仅有2个查询的示例。
SELECT [Q1].Sensor, [Q1].Min1, [Q2].Min2
FROM Q2 INNER JOIN Q1 ON [Q2].Sensor = [Q1].Sensor
ORDER BY [Q1].Sensor;
输出(两个表使用相同的样本数据):
Sensor Min1 Min2
T01 58.85883 58.85883
T02 75.03191 75.03191
T03 -72.77819 -72.77819
T04 -61.54791 -61.54791
T05 84.16943 84.16943
T06 45.98995 45.98995
如果这太难以管理和/或执行速度太慢以至于不切实际,那么VBA只会采用其他方法。请参阅https://www.access-programmers.co.uk/forums/showthread.php?t=299864中类似要求的示例。