【问题标题】:SQL Server query to create a new column for each date within a rangeSQL Server 查询为范围内的每个日期创建一个新列
【发布时间】:2013-03-23 00:31:20
【问题描述】:

我有一个程序让用户选择一个日期范围,然后它会查询 SQL 服务器数据库以检索他们使用小时数的日期。我想将日期放在自己的列中,而不是全部放在同一个列中。例如:

Employee   Total Hours  Monday 3/10  Tuesday 3/11 ....
Doe, John    40             8             8

这是现在的查询:

SELECT e.emp_fullname, t.tc_hours, t.punchDate 
FROM WaspTime.dbo.vEmployeeInfo as e, WaspTime.dbo.vTimeCards as t 
WHERE e.emp_id = t.tc_emp 
AND t.punchDate >= '03/10/2013'
AND t.punchDate <= '03/20/2013'

结果如下:

Smith, Dan  8  2013-03-10 00:00:00.000
Smith, Dan  8 2013-03-11 00:00:00.000   

【问题讨论】:

  • 您有日期表还是仅基于可用日期?
  • 源数据结构是什么?我们只是根据您现有的查询进行猜测。
  • 对“sql server pivot query”进行谷歌搜索
  • 您也可以使用 Dsql 来实现这一点,尽管枢轴解决方案可能会更好。
  • 我希望在 Excel 而不是 DB 中进行最后的数据透视,因为它更容易做到。

标签: sql sql-server date


【解决方案1】:

类似这样的事情,无论你有多少时间都重复。

我假设你会:

  • 需要SUM(或COUNT?)您的工作时间吗?
  • 使用某种@period_start_date 参数,然后将每个周期偏移一天、2 天、3 天等...

在文本编辑器中手工完成,所以请原谅拼写错误,或者如果事情只是简单地不起作用 - 但我认为这个想法是清晰/合理的。

CREATE PROCEDURE GetHoursWorkedInPeriod @periodStartDate datetime = getdate() AS
SELECT 
e.emp_fullname, 
sum(t1.tc_hours) as 'Day1Hours', 
min(t1.punchDate) as 'Day1Date'.

sum(t2.tc_hours) as 'Day2Hours', 
min(t2.punchDate) as 'Day2Date',

sum(t3.tc_hours) as 'Day3Hours', 
min(t3.punchDate) as 'Day3Date',

...and so on

FROM 
WaspTime.dbo.vEmployeeInfo as e

inner join WaspTime.dbo.vTimeCards as t1
on e.emp_id = t1.tc_emp 
AND t1.punchDate >= DATEADD (day , 0 , @periodStartDate )
AND t1.punchDate < DATEADD (day , 1 , @periodStartDate )

inner join WaspTime.dbo.vTimeCards as t2
on e.emp_id = t2.tc_emp 
AND t2.punchDate >= DATEADD (day , 1 , @periodStartDate )
AND t2.punchDate < DATEADD (day , 2 , @periodStartDate )

inner join WaspTime.dbo.vTimeCards as t3
on e.emp_id = t3.tc_emp 
AND t3.punchDate >= DATEADD (day , 2 , @periodStartDate )
AND t3.punchDate < DATEADD (day , 3 , @periodStartDate )

...and so on.

GROUP BY
e.emp_fullname

根据 OP 的要求将每个时间段限制为一天,并在结果集中明确包括小时数的适用日期。

【讨论】:

  • 那么我是否必须为我想要的每一天创建一个联接?有没有办法让我动态地做到这一点?时间跨度通常为两周,但我希望它比这更灵活一些。
  • @Nicknack1016 使用这种方法(我刚刚将其更新为 SP),您只需要一次性剪切/粘贴重复位并更新偏移量,例如 14次(或者说 31 覆盖一个月)来完成 SP 实施。然后您使用此 SP 的代码指定期间开始日期,然后仅动态选择它感兴趣的 "Day" + dayNumber + "Hours""Day" + dayNumber + "Date" 列。或者最好不要在 SP 中使用 DayXHoursDayXDate,使用 HoursXDateX 以便您可以选择 "Hours" + dayNumber"Date" + dayNumber
  • @Nicknack1016 感谢您的接受,非常感谢。我很想知道您是否真的在使用这个解决方案?如果是这样 - 如果它不太正确,我们很乐意继续提供帮助(只要我们保持在您问题的现有范围内)。
  • 没问题 =) 它确实有帮助。我正在使用它,但我试图以一种可以找到给定日期的星期几的方式进行调整,即星期一给定 3/11/13,并将其作为列标题而不是“Day1Hours”。一旦我得到了这个,以及一个总小时数列,一切都应该是完美的。
  • @Nicknack1016 要获取日期名称,请使用 datename(dw, t1.punchdate)。如果您需要将其作为 SQL 中的列标题,则需要构建一个动态 SQL 字符串,并将这些值作为列别名注入/连接。但是,如果报告服务或其他一些程序化客户端使用此查询,那么只需将这些日期名称作为选择列表的一部分传回,就可以将它们用作标题。总小时数,如该期间的总小时数? Sum(t1.hours) + sum(t2.hours) + .. + sum(tN.hours) as TotalHours。如果您希望更新答案以动态生成 SQL,请告诉我。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-26
  • 2015-07-27
  • 1970-01-01
相关资源
最近更新 更多