子查询返回超过1个具有特定日期的值

时间:2015-07-30 16:09:51

标签: sql sql-server

我有一个包含以下结构的表

CREATE TABLE #T_TrailingYearHours (
    RecordDate [DATE],
    Level5Location [VARCHAR](255),
    Hours [Float]
)
GO

其中包含每个地点(2013-07至2015-06)过去两年的数据

从每个位置的第一个条目(2013-07)开始,“小时”列是之前所有小时的累积总和,因此当我到达2015-06的条目时,它将是最后两个小时的总小时数年。

我想创建一个基于上述表格的表格,仅查看过去12个月(06-2014至06-2015),并显示每个月过去12个月的累计小时数。因此,对于07年至2014年,它将是07-2013和07-2014之间的累计小时数。

我有以下查询:

DECLARE @CurrentMonth int
DECLARE @CurrentYear int

SET @CurrentMonth = MONTH(GETDATE())
SET @CurrentYear = YEAR(GETDATE())

INSERT INTO #t_trailing12hours 
SELECT T.recorddate, 
       T.level5location, 
       T.hours - (SELECT TH.hours 
        FROM   #t_trailingyearhours TH 
        WHERE  TH.level5location = T.level5location 
               AND ( Year(TH.recorddate) = ( Year(T.recorddate) - 1 ) 
                     AND Month(TH.recorddate) = Month(T.recorddate) )) 
FROM   #t_trailingyearhours T 
WHERE  ( Year(T.recorddate) >= @CurrentYear - 1 
         AND Month(T.recorddate) >= @CurrentMonth ) 
        OR ( Year(T.recorddate) = @CurrentYear 
             AND Month(T.recorddate) < @CurrentMonth ) 

但我收到错误:

  

Msg 512,Level 16,State 1,Line 14   子查询返回的值超过1。子查询遵循=,!=,&lt;,&lt; =,&gt;,&gt; =或使用子查询时不允许这样做   作为表达。

因此,我试图将其分解为仅仅一个日期的简单案例,而不是一年的范围,并且它适用于2015年的所有日期:

SELECT T.recorddate, 
       T.level5location, 
       T.hours - (SELECT TH.hours 
                  FROM   #t_trailingyearhours TH 
                  WHERE  TH.level5location = T.level5location 
                         AND ( Year(TH.recorddate) = ( Year(T.recorddate) - 1 ) 
                               AND Month(TH.recorddate) = Month(T.recorddate) )) 
FROM   #t_trailingyearhours AS T 
WHERE  T.recorddate = '2015-06-30' 

我尝试从2014-07-31到2014-12-31查询的任何内容都会出现与上述相同的错误。由于某种原因,它在子查询中返回多个结果,我错过了原因。我在查询中做错了什么,有什么我应该做的不同吗?

1 个答案:

答案 0 :(得分:2)

您需要了解子查询的工作原理。

我认为您需要Inner Join而不是sub-query

INSERT INTO #t_trailing12hours 
SELECT T.recorddate, 
       T.level5location, 
       T.hours - TH.hours 
FROM   #t_trailingyearhours T 
       INNER JOIN #t_trailingyearhours TH 
               ON TH.level5location = T.level5location 
                  AND ( Year(TH.recorddate) = ( Year(T.recorddate) - 1 ) 
                        AND Month(TH.recorddate) = Month(T.recorddate) ) 
WHERE  ( Year(T.recorddate) >= @CurrentYear - 1 
         AND Month(T.recorddate) >= @CurrentMonth ) 
        OR ( Year(T.recorddate) = @CurrentYear 
             AND Month(T.recorddate) < @CurrentMonth )