FROM子句中的SQL子查询

时间:2015-01-23 23:31:09

标签: mysql sql

我发现了一些处理这个问题的问题,似乎MySQL并不允许这样做。没问题,我 在FROM子句中有子查询。但是,我不知道如何绕过它。这是我的设置:

我有一个包含我想要的3列的度量表:ControllerID,TimeStamp和State。基本上,数据收集引擎每5分钟与数据库中的每个控制器联系,并在度量表中粘贴一个条目。该表包含这三列,以及我不关心的MetricsID。也许有更好的方法来存储这些指标,但我不知道。 无论如何,我想要一个视图,它为每个不同的ControllerID获取最新的TimeStamp,并获取TimeStamp,ControllerID和State。因此,如果有4个控制器,视图应该总是有4行,每个行都有不同的控制器,以及最近的状态。

我已经能够创建一个获得我想要的查询,但它依赖于FROM子句中的子查询,这在视图中是不允许的。以下是我到目前为止的情况:

SELECT *
FROM
    (SELECT 
    ControllerID, TimeStamp, State
    FROM Metrics
    ORDER BY TimeStamp DESC)
AS t
GROUP BY ControllerID;
像我说的那样,这很有效。但我不能在视图中使用它。我尝试过使用max()函数,但按照此处:SQL: Any straightforward way to order results FIRST, THEN group by another column?如果我想要除GROUP BY和ORDER BY列之外的任何其他列,则max()不起作用。我已经证实了这个限制,但是它没有用。

我还试图通过TimeStamp改变指标表。这也不起作用;保留错误的行。

编辑:以下是我提取的Metrics表的SHOW CREATE TABLE

 CREATE TABLE Metrics (
  MetricsID int(11) NOT NULL AUTO_INCREMENT,
  ControllerID int(11) NOT NULL,
  TimeStamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  State tinyint(4) NOT NULL,
  PRIMARY KEY (MetricsID),
  KEY makeItFast (ControllerID,MetricsID),
  KEY fast (ControllerID,TimeStamp),
  KEY fast2 (MetricsID),
  KEY MetricsID (MetricsID),
  KEY TimeStamp (TimeStamp)
) ENGINE=InnoDB AUTO_INCREMENT=8958 DEFAULT CHARSET=latin1

2 个答案:

答案 0 :(得分:2)

如果您想要每个控制器的最新行,以下是查看友好的:

SELECT ControllerID, TimeStamp, State
FROM Metrics m
WHERE NOT EXISTS (SELECT 1
                  FROM Metrics m2
                  WHERE m2.ControllerId = m.ControllerId and m2.Timestamp > m.TimeStamp
                 );

无论如何,您的查询不正确,因为它使用的MySQL扩展无法保证正常工作。 state的值不是来自具有最大时间戳的行。它来自任意一行。

编辑:

为获得最佳效果,您需要Metrics(ControllerId, Timestamp)上的索引。

答案 1 :(得分:1)

修改抱歉,我误解了你的问题;我以为你试图克服视图中的嵌套查询限制。

您正尝试显示每个不同ControllerID的最新行。此外,你正试图用视图来做。

首先,我们来做吧。如果您的MetricsID列(我知道您不关心)是自动增量列,这非常简单。

SELECT ControllerId, TimeStamp, State
  FROM Metrics m
  WHERE MetricsID IN (
              SELECT MAX(MetricsID) MetricsID
                FROM Metrics
               GROUP BY ControllerID) 
  ORDER BY ControllerID 

此查询使用MAX ... GROUP BY为每个控制器提取编号最大(最近)的行。 可以成为一个视图。

(ControllerID, MetricsID)上的复合索引将能够以高效loose index scan满足子查询。

我混淆的根本原因:我没有仔细阅读你的问题。

您混淆的根本原因:您正在尝试利用对GROUP BY的恶意MySQL扩展。您订购子查询的想法可能有效。但是你暂时的成功是目前实施的偶然副作用。阅读:http://dev.mysql.com/doc/refman/5.6/en/group-by-handling.html