数据历史记录查询

时间:2009-11-13 16:01:58

标签: sql-server

我有一个包含电动机数据的表,格式为:

DATE(日期时间)| TagName(VarChar(50)| Val(Float)|


2009-11-03 17:44:13.000 | Motor_1 | 123.45


2009-11-04 17:44:13.000 | Motor_1 | 124.45


2009-11-05 17:44:13.000 | Motor_1 | 125.45


2009-11-03 17:44:13.000 | Motor_2 | 223.45


2009-11-04 17:44:13.000 | Motor_2 | 224.45

每天插入每个电机的数据,因此将有31个Motor_1和31个 Motor_2s等我们这样做,所以我们可以在我们的控制系统显示器上趋势。 我正在使用视图提取最后几个月的最大值和最后几个月的最小值。 本月数据也是如此。然后我加入两个并计算差异 获得该月的实际运行时间。 “Val”是不可见的 来自PLC(控制器)的累积。这是我对Last months Max的查询 值:

SELECT     TagName, Val AS Hours
FROM         dbo.All_Data_From_Last_Mon AS cur
WHERE     (NOT EXISTS
                          (SELECT     TagName, Val
                            FROM          dbo.All_Data_From_Last_Mon AS high
                            WHERE      (TagName = cur.TagName) AND (Val > cur.Val)))

这是我对Last months Max的查询 值:

SELECT     TagName, Val AS Hours
FROM         dbo.All_Data_From_Last_Mon AS cur
WHERE     (NOT EXISTS
                          (SELECT     TagName, Val
                            FROM          dbo.All_Data_From_Last_Mon AS high
                            WHERE      (TagName = cur.TagName) AND (Val < cur.Val)))

这是计算差异并且运行有点慢的查询:

SELECT  dbo.Motors_Last_Mon_Max.TagName, STR(dbo.Motors_Last_Mon_Max.Hours - dbo.Motors_Last_Mon_Min.Hours, 12, 2) AS Hours
FROM    dbo.Motors_Last_Mon_Min RIGHT OUTER JOIN
            dbo.Motors_Last_Mon_Max ON dbo.Motors_Last_Mon_Min.TagName = dbo.Motors_Last_Mon_Max.TagName

我知道有更好的方法。最终我只需要上个月的总数和这几个月的总数。任何帮助将不胜感激。

提前致谢

1 个答案:

答案 0 :(得分:0)

前两个查询可以作为一个处理。类似的东西:

SELECT TagName, MAX(Val) AS MaxVal, MIN(Val) AS MinVal
FROM   dbo.All_Data_From_Last_Mon
GROUP BY TagName
-- ORDER BY TagName  (optionally)

我现在看到这些查询是SQL视图,用于第三个查询...我可以看到为什么这会很慢;-)
下面重现了逻辑,但是没有视图,这应该允许SQL进行相当多的优化。无论如何,它提供了更清晰的做法...... 请“给它旋转”。

SELECT  DISTINCT Mx.TagName, STR(Mx.Hours - Mn.Hours, 12, 2) AS Hours
FROM  dbo.All_Data_From_Last_Mon Mx
RIGHT OUTER JOIN dbo.All_Data_From_Last_Mon Mn ON Mx.TagName = Mn.TagName
  AND dbo.All_Data_From_Last_Mon  -- Cut the cross product a bit; may not be necessary
WHERE 
      NOT EXISTS (SELECT * FROM dbo.All_Data_From_Last_Mon Mx1 
                  WHERE Mx1.TagName = Mx.TagName AND Mx1.Hours > Mx.Hours)
  AND NOT EXISTS (SELECT * FROM dbo.All_Data_From_Last_Mon Mn1 
                  WHERE Mn1.TagName = Mn.TagName AND Mn1.Hours < Mx.Hours)

注意:
  - 注意SELECT语句中的DISTINCT。这是为了避免重复行,如果有几天显示该月的最大(或最小)小时值。
  - 连接的额外条件旨在避免完整的31 * 31交叉产品,但真正将其带到单行(或多个情况下为多个)的条件是随后的非现有谓词。   - TagName + Hours索引,如果不容易出现将会有很大帮助。

==&GT;我对这个查询性能的反馈感兴趣,与实际数据一起运行。