我的查询给了我错误的ID

时间:2012-05-15 17:01:35

标签: sql sqlite

我有四个表:A,B,C,D。D有一个FK到C,C有一个FK到B,B有一个FK到A.每个表都有一个ID列。除了ID和CID之外,表D还有Value和Timestamp(整数)。给定一定时间,我需要在时间戳之前从D开始的行,但是对于每个CID最接近它 - 除非在时间戳之前没有行,在这种情况下我需要在时间戳之后的第一个值。我正在使用Sqlite。

退出最后一个要求,我尝试使用此查询获取Timestamp之前的值,但返回的ID是错误的:

SELECT  * 
FROM    D d 
INNER JOIN C c ON d.CID = c.ID 
INNER JOIN B b ON C.BID = b.ID
WHERE   b.AID = @AID AND d.Timestamp = 
        (
        SELECT  MAX(d2.Timestamp) 
        FROM    D d2 
        WHERE   d2.Timestamp < @StartTime 
                AND d2.CID = D.CID
        )

2 个答案:

答案 0 :(得分:1)

此查询应在查询的第一部分(在UNION ALL之前)获取@StartTime之前的最后一个条目,然后将其与@StartTime之后的第一个条目组合。剩下的就是为每个CID选择最小的条目。

SELECT d2.*
FROM (
  SELECT D.ID, MAX(D.Timestamp)
  FROM D d
    INNER JOIN C c ON c.ID = d.CID
      INNER JOIN B b on b.ID = c.BID
  WHERE b.AID = @AID AND d.Timestamp <= @StartTime 
  GROUP BY d.CID) AS results
INNER JOIN D d2 ON d2.ID = results.ID

UNION ALL 

SELECT d2.*
FROM (
  SELECT D.ID, MIN(D.Timestamp)
  FROM D d
    INNER JOIN C c ON c.ID = d.CID
      INNER JOIN B b on b.ID = c.BID
  WHERE b.AID = @AID AND d.Timestamp > @StartTime 
  GROUP BY d.CID) AS results
INNER JOIN D d2 ON d2.ID = results.ID

答案 1 :(得分:0)

这可能会奏效,但仍然会对你想要的东西感到困惑。

SELECT  *,
(CASE WHEN d.Timestamp < @StartTime THEN 1 ELSE 0) AS timeCheck
FROM    D d 
INNER JOIN C c ON d.CID = c.ID 
INNER JOIN B b ON C.BID = b.ID
WHERE   b.AID = @AID
ORDER BY timeCheck DESC, d.Timestamp DESC
LIMIT 0,1

更新