如何在SQL中的DateTime字段上运行Sum并使用单列连接

时间:2013-08-07 18:00:43

标签: sql-server

使用SSMS(SQL Server Management Studio) - 2012

请帮我完成构建此SQL查询。

第一张表Sites

 Client,Market,Project,SiteNumber
  grum , lad  , aaa   , 12345
  gla  , daa  , h11   , 56789

第二张表SitesStatus

SiteNumber,StatusName,Date(DateTime),ByUser
12345   ,  sta1    , 8/7/13 15:33:22, hec
12345   ,  sta1    , 8/7/13 15:43:22, hec
12345   ,  sta2    , 8/7/13 15:53:22, hec
12345   ,  sta2    , 8/7/13 16:03:22, hec
12345   ,  sta2    , 8/7/13 16:13:22, hec
56789   ,  sta1    , 8/7/13 15:22:22, hec
56789   ,  sta2    , 8/7/13 15:32:22, hec

期望的结果

Client,Market,Project,TotalSites,   sta1   ,TotStatTime,    sta2   ,TotStat2Time,ByUser
 Grum ,  lad ,  aaa  ,     5    ,     2    ,     10    ,     3     ,     20     , hec
 gla  , daa  ,  h11  ,     2    ,     1    , inprogress,     1     , inprogress , hec

它必须显示表2中Date列的所有行的小时数与表1中的sitenumber相对应,但也要将inprogress放入结果的列/行中如果没有找到要计算的数字。 (如果不可能的话,我也可以在我的代码中执行此操作。)此外,它可能有一个值,但还没有“最后一个值”,如时钟但没有时钟输出时间。

请记住所有状态都是已知的,不会改变。 (所以我知道我只有X个状态,本例中X为2。)

到目前为止我尝试过:

select 
  Client,
  Market,
  ProjectType,
  count(*) as Total,
  sum(case when StatusName = 'sta1' then 1 else 0 end) as 'sta1',
  sum(case when StatusName = 'sta2' then 1 else 0 end) as 'sta2'

--Here is where I'd like to add the Time adding for the joined table2

from
  Sites s
INNER JOIN SitesStatus ss
on s.sitenumber = ss.SiteNumber

where
  (StatusName in (
  'sta1', 
  'sta2', 
  ) 
  )
group by
  Client,
  Market,
  ProjectType

@Andi M编辑:

我说 - 这里是我要为上面的联接table2添加时间添加的地方,我想知道为列日期添加所有行的逻辑(DateTime)给Sitenumbers和状态匹配

所以12345有2个sta1条目 1 起始条目 2 我要添加/减去的条目以从第一个条目中获取时间

12345还有3个sta2条目我们将添加/减去第一个条目以获得时间。

56789有1个sta1和1个sta2,我希望代码显示的时间是( - )或(inProgress),因为它没有最终值....

更清楚了吗?

2 个答案:

答案 0 :(得分:2)

在最基本的形式中,修改查询以返回所需的额外数据位的一种方法是:

select 
  s.Client,
  s.Market,
  s.ProjectType,
  count(*) as Total,
  sum(case when ss.StatusName = 'sta1' then 1 else 0 end) as sta1,
  sum(case when ss.StatusName = 'sta2' then 1 else 0 end) as sta2,
  datediff(
    minute,
    min(case ss.StatusName when 'sta1' then ss.Date end),
    max(case ss.StatusName when 'sta1' then ss.Date end)
  ) as TotSta1Time,
  datediff(
    minute,
    min(case ss.StatusName when 'sta2' then ss.Date end),
    max(case ss.StatusName when 'sta2' then ss.Date end)
  ) as TotSta2Time

from
  Sites s
INNER JOIN SitesStatus ss
on s.sitenumber = ss.SiteNumber

where (
  StatusName in (
    'sta1', 
    'sta2', 
  ) 
)
group by
  Client,
  Market,
  ProjectType
;

对于只包含一行的组,min()max()都会返回相同的值,因此datediff()将计算为0.将0转换为{{ 1}}是可能的,但请注意,这将在同一列中混合不同的类型。您可能需要考虑返回NULL而不是在应用程序中将它们解释为'inprogress'。为此,您只需将inprogress次调用放在datediff s:

nullif()

但是,如果您完全确定需要查询返回准备显示结果,就像在所需结果中一样,您只需要为两个新表达式中的每一个添加两个函数调用,一个{{ 1}} / ... nullif( datediff( minute, min(case ss.StatusName when 'sta1' then ss.Date end), max(case ss.StatusName when 'sta1' then ss.Date end) ), 0 ) as TotSta1Time, nullif( datediff( minute, min(case ss.StatusName when 'sta2' then ss.Date end), max(case ss.StatusName when 'sta2' then ss.Date end) ), 0 ) as TotSta2Time ...CAST和一个CONVERT / varchar将NULL默认为ISNULL

COALESCE

答案 1 :(得分:0)

我想知道你是否在PIVOT操作之后,原始查询中的一个或多个字段被转换为列标题,其中透视结果是摘要信息。 Here's some links让你开始。