SQL Server - 在同一查询中获取每周和每日总计

时间:2014-12-17 13:45:47

标签: sql-server date

在我的查询中,我目前正在努力获取设定日期范围内的字段总数,我还希望查询显示一天的总数。

例如我目前的结果是这样的:

ID, UserID, uname, totals
1     1     admin   3
2     3     test    6
3     4     user    2

我希望我的结果如下:

ID, UserID, uname, totals, todaytotal
1     1     admin   3,      1
2     3     test    6,      2
3     4     user    2,      2

此处的数据是随机的,但仅用于视觉目的。

总计从名为ActivityLog的表中获取数量总和

我的查询是这样的,使用日期范围:

SELECT al.UserID, 
od.CardNumber as uname, 
Sum(isnull(cast(ActualQuantity as float),0)) totals
from ActivityLog al , OperatorDetail od 
WHERE
od.ID = al.UserID AND
StartDateTime >= '2014-08-24 00:00:00.000' 
AND EndDateTime <= '2014-08-31 23:59:59.000' 
group by al.UserID, od.CardNumber
order by od.CardNumber 

这是我尝试从特定日期(今天总计2014-08-29)获得总数的尝试

SELECT al.UserID, 
od.CardNumber as uname, 
Sum(isnull(cast(ActualQuantity as float),0)) totals,

(select Sum(isnull(cast(ACTL.ActualQuantity as float),0)) totaltoday 
from ActivityLog ACTL, OperatorDetail OPD 
WHERE
ACTL.UserID = OPD.ID
AND
al.StartDateTime >= '2014-08-29 00:00:00.000'  -- same date (one day)
AND al.EndDateTime <= '2014-08-29 23:59:59.000'  -- same date (one day)
GROUP BY ACTL.UserID, OPD.CardNumber
) as todaytotal

from ActivityLog al , OperatorDetail od 
WHERE 
od.ID = al.UserID AND
StartDateTime >= '2014-08-24 00:00:00.000' 
AND EndDateTime <= '2014-08-31 23:59:59.000' 
group by al.UserID, od.CardNumber, al.StartDateTime, al.EndDateTime
order by od.CardNumber 

有了这个,我得到了这个错误:

  

子查询返回的值超过1。这是不允许的   子查询跟随=,!=,&lt;,&lt; =,&gt;,&gt; =或当子查询用作   表达。

我怎样才能做到这一点?

3 个答案:

答案 0 :(得分:1)

您可以使用条件聚合:

select al.UserID, 
       od.CardNumber as uname, 
       isnull(Sum(cast(ActualQuantity as float)), 0) totals,
       isnull(Sum(case when StartDateTime >= '2014-08-31' and StartDateTime < '2014-09-01'
                       then cast(ActualQuantity as float)
                  end), 0))  totals,
from ActivityLog al join
     OperatorDetail od 
     on od.ID = al.UserID 
where StartDateTime >= '2014-08-24' AND EndDateTime < '2014-09-01' 
group by al.UserID, od.CardNumber
order by od.CardNumber ;

请注意,我更改了日期算术。不要使用<=作为上限,而是使用<作为下一个日期。那么你不必担心在午夜之前发生的任何事情。

我修复了join语法。另外,我将isnull() 放在<{1}}之外而不是内部。即使与sum()没有匹配项,也会给出0的值。而且,您应该将case存储为数值,因此ActualQuantity应该是不必要的。

最后,如果您想要当前日期:

cast()

请确保当前日期在 isnull(Sum(case when StartDateTime >= cast(getdate() as date) and StartDateTime < cast(getdate() + 1 as date) then cast(ActualQuantity as float) end), 0)) totals,

的范围内

答案 1 :(得分:1)

我认为你的查询在语法上是正确的。

从记忆中书写:尝试

SELECT al.UserID, 
  od.CardNumber as uname, 
  Sum(isnull(cast(ActualQuantity as float),0)) totals,
  Sum(case when cast(StartDateTime as date) = cast(getdate() as date) then isnull(cast(ActualQuantity as float),0)) else 0 end) TodayTotals
from ActivityLog al , OperatorDetail od 
WHERE
  od.ID = al.UserID AND
  StartDateTime >= '2014-08-24 00:00:00.000' 
  AND EndDateTime <= '2014-08-31 23:59:59.000' 
 group by al.UserID, od.CardNumber
order by od.CardNumber 

CASTdate适用于SQL SERVER&gt; = 2008

答案 2 :(得分:1)

您得到的错误是因为您的子查询计算今天总计的总和为列返回多个值。为什么要创建完全独立的子查询。我在子查询中找不到与OLD一起加入的需要,只需使用来自outsid的数据。你可以这样做

SELECT al.UserID, 
od.CardNumber as uname, 
Sum(isnull(cast(ActualQuantity as float),0)) totals,

(select Top 1 Sum(isnull(cast(ACTL.ActualQuantity as float),0)) totaltoday 
from ActivityLog ACTL
WHERE
ACTL.UserID = a1.ID            --OPD.ID Commented this just use a1's id
AND
CAST (StartDateTime AS DATETIME) = GETDATE() -- logically today's date should be GETDATE isn't it?
) as todaytotal

from ActivityLog al , OperatorDetail od 
WHERE 
od.ID = al.UserID AND
StartDateTime >= '2014-08-24 00:00:00.000' 
AND EndDateTime <= '2014-08-31 23:59:59.000' 
group by al.UserID, od.CardNumber, al.StartDateTime, al.EndDateTime
order by od.CardNumber 

我会这样说但是,你的方式效率不高,请使用Gordan Linoff的建议