用于将日期段拆分为相应员工ID的每个日期的SQL查询

时间:2011-03-21 08:02:10

标签: sql

我有一个名为“Employee”的表...它有3个字段:

  1. empid
  2. 从日期开始
  3. TODATE
  4. 我想将相应的 emp id 的日期(从从日期到日期之间的日期,包括两者的日期)分开。

    例如,这是我得到的表格:

    emp id        from date          to date
      1           1/1/2011           3/1/2011
      2           5/1/2011           5/1/2011
    

    由此我想得到这个:

    1         1/1/2011
    1         2/1/2011
    1         3/1/2011
    2         5/1/2011
    

    什么是为我这样做的SQL查询?

2 个答案:

答案 0 :(得分:2)

你想......我给...

;with Employee([emp id],[from date],[to date]) as (
    select 1, convert(datetime,'20110101'), convert(datetime,'20110103') union all
    select 2, '20010105', '20110105'
)

-- your query below here
select [emp id], [from date] + w.number*1000 + v.number [the date]
from Employee e
inner join master..spt_values w
    on w.type='P' and w.number <= datediff(d, [from date], [to date]) % 1000
inner join master..spt_values v
    on v.type='P'
       and v.number <= 999
       and (w.number*1000) + v.number <= datediff(d, [from date], [to date])
order by [emp id], [the date]

如果您一次处理的时间超过6年,这是一个更简单的版本

select [emp id], [from date] + v.number [the date]
from Employee e
inner join master..spt_values v
    on v.type='P'
       and v.number <= datediff(d, [from date], [to date])
order by [emp id], [the date]

答案 1 :(得分:1)

使用递归CTE的解决方案(适用于SQL Server 2005 +):

WITH Employee (emp_id, from_date, to_date) AS (
  /* this is just a sample data definition */
  SELECT 1, CAST('20110101' AS datetime), CAST('20110103' AS datetime) UNION ALL
  SELECT 2, CAST('20110105' AS datetime), CAST('20110105' AS datetime)
),
unrolled AS (
  /* and this is the recursive CTE */
  SELECT
    emp_id,
    from_date AS date
  FROM Employee
  UNION ALL
  SELECT
    r.emp_id,
    DATEADD(day, 1, r.date)
  FROM Employee e
    INNER JOIN unrolled r
      ON e.emp_id = r.emp_id AND e.to_date > r.date
)
SELECT * FROM unrolled
ORDER BY emp_id, date