0

我不是 sql 专家,但遇到了这个问题:

我必须从 Microsoft SQL 2008 服务器检索数据。它保存来自不同探头的不同测量数据,这些数据没有任何记录间隔。这意味着某些探针可以每周传输一次数据库中的数据,另一个可以每秒传输一次。探针由 id(不是唯一的)标识,重点是仅检索每个 id(探针)的最后一条记录。表如下所示(最后 5 个,按 SampleDateTime desc 排序):

TagID   SampleDateTime  SampleValue     QualityID
13      634720670797944946      112     192
23      634720670797944946      38.1    192
17      634720670797944946      107.5   192
14      634720670748012090      110.6   192
19      634720670748012090      99.7    192

我无法修改服务器甚至设置,只能进行查询。而且我需要以均匀的间隔(比如每分钟左右一次)检索请求的数据。有超过 100 个探针(具有不同的 id),其中大约 40 个需要读取。所以我猜测如果这可以在单个查询中完成,它可能比在单独的查询中获取每一行更有效。

使用 MySQL 和类似的表以这种方式获得了预期的结果(高度赞赏的更好方法的建议!):

SELECT TagID,SampleDateTime,SampleValue FROM 
(
    SELECT TagID,SampleDateTime,SampleValue FROM measurements 
    WHERE TagID IN(101,102,103) ORDER BY SampleDateTime DESC
) 
AS table1 GROUP BY TagID;

认为这可以解决问题(没有使用 MAX() 或 DISTINCT 或无论我尝试什么),即使使用正确的数据也是如此。但由于“GROUP BY”,它自然不能在 SQL 女士中工作。

Column 'table1.SampleValue' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

我非常坚持这一点,因此任何见解都会受到欢迎。

4

1 回答 1

1

我有点困惑,因为您标记了 MySQL 和 SQL-Server。对于 SQL-Server,我会使用该ROW_NUMBER函数来协助:

SELECT  m.TagID, m.SampleDateTime, m.SampleValue, m.QualityID
FROM    (   SELECT  *, ROW_NUMBER() OVER(PARTITION BY TagID ORDER BY SampleDateTime DESC) [RowNumber]
            FROM    Measurements 
        ) m
WHERE   Rownumber = 1

ROW_NUMBER函数完全按照它在锡上所说的那样做,根据您提供的标准给每一行一个数字。因此,在上面的示例中,每次遇到新的 TagID 时都从 1 重新开始PARTITION BY TagID。告诉从最近的条目开始对每个 TagID 进行编号,然后向上工作到最早的条目。ROW_NUMBERORDER BY SampleDateTime DESCROW_NUMBER

您的查询失败的原因是因为 MySQL 允许隐式分组,这意味着因为您只指定GROUP BY TagID了选择列表中且未包含在聚合函数中的任何字段,将获得分配给它们的“随机”行的值(您的案例中的最新行,因为您ORDER BY SampleDateTime DESC在子查询中指定了。

以防万一需要以下内容应该在大多数 DBMS 中工作,并且是生成与您在 MySQL 中运行的查询类似的查询的更好方法:

SELECT  m.TagID, m.SampleDateTime, m.SampleValue, m.QualityID
FROM    Measurements m
        INNER JOIN
        (   SELECT  TagID, MAX(SampleDateTime) AS SampleDateTime
            FROM    Measurements
            GROUP BY TagID
        ) MaxTag
            ON MaxTag.TagID = m.TagID
            AND MaxTag.SampleDateTime = m.SampleDateTime
于 2012-05-08T11:10:51.033 回答