3

使用 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 中与表 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 编辑:

我说的地方-这里是我想为上面连接的表2添加时间的地方,我想知道为列日期(日期时间)添加所有行的逻辑,给出站点编号和状态匹配

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

12345 也有 3 个 sta2 条目,我们将从第一个条目中添加/减去最后一个条目以获得时间。

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

还有更清楚的吗?

4

2 回答 2

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 变为'inprogress'是可能的,但请注意,这将在同一列中混合不同的类型。您可能想考虑只返回 NULL 并将它们解释为inprogress在您的应用程序中。为此,您只需将datediff调用放在nullif()s 中:

...
  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
...

但是,如果您绝对确定需要查询返回准备显示的结果,就像在您的 Desired Results 中一样,您只需要向两个新表达式中的每一个添加两个函数调用,一个CAST/CONVERT到 avarchar和一个ISNULL/COALESCE将 NULL 默认为'inprogress'

...
  coalesce(
    convert(
      varchar(10),
      nullif(
        datediff(
          minute,
          min(case ss.StatusName when 'sta1' then ss.Date end),
          max(case ss.StatusName when 'sta1' then ss.Date end)
        ),
        0
      )
    ),
    'inprogress'
  ) as TotSta1Time,
  coalesce(
    convert(
      varchar(10),
      nullif(
        datediff(
          minute,
          min(case ss.StatusName when 'sta2' then ss.Date end),
          max(case ss.StatusName when 'sta2' then ss.Date end)
        ),
        0
      )
    ),
    'inprogress'
  ) as TotSta2Time
...
于 2013-08-09T19:10:25.133 回答
0

我想知道您是否在执行 PIVOT 操作后,将原始查询中的一个或多个字段转换为列标题,转置结果为摘要信息。这里 有一些 链接可以帮助您入门。

于 2013-08-09T01:43:27.123 回答