2017-09-14 83 views
-2

I have my table valus like in image我想选择在SQL

我想通过DaysCount列 迭代开始日期值,请别人帮我写的SQL Server查询,以便我可以执行要求的动态范围内的所有日期。

在此先感谢。

+0

是提供足够的信息。另外,你没有提出具体的问题。 – JohnH

回答

0

您还没有一个明确的答案提供了足够的信息,但如果所有你想要做的是让在日期列中的所有日期:

SELECT StartDates AS Dates 
FROM table_name 
+0

我想迭代startdate到DaysCount列值 – Nadeem

1

你的问题是缺乏大量的清晰但我真的明白你想在这里。完成此操作的最佳方法是使用统计表。我保留一个作为我的系统中的一个视图。

create View [dbo].[cteTally] as 

WITH 
    E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)), 
    E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows 
    E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max 
    cteTally(N) AS 
    (
     SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4 
    ) 
select N from cteTally 

现在,我们需要一个表来开始持有我们的数据。这是你应该在未来发布的内容。然后,我们可以简单地利用我们的理货表的权力,瞧,问题很简单。

declare @SomeTable table 
(
    StartDate date 
    , DaysCount int 
) 

insert @SomeTable 
select '2017-06-23', 1 union all 
select '2017-06-26', 3 union all 
select '2017-08-07', 1 

select MyDate = dateadd(day, t.N - 1, st.StartDate) 
from @SomeTable st 
join cteTally t on t.N <= st.DaysCount 
order by st.StartDate 
    , t.N 

这将输出:

2017-06-23 
2017-06-26 
2017-06-27 
2017-06-28 
2017-08-07 

- 编辑 - 我会强烈建议使用符合表像我张贴,因为它是在这么许多情况下非常有用。但有时候这是行不通的。没问题。这是一种你可以内联的方式。请注意,由于您似乎并不需要太多的数值,因此我在这里也做了相当短的统计表。

WITH 
    E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)), 
    E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows 
    cteTally(N) AS 
    (
     SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E2 
    ) 

select MyDate = dateadd(day, t.N - 1, st.StartDate) 
from @SomeTable st 
join cteTally t on t.N <= st.DaysCount 
order by st.StartDate 
    , t.N 
+0

我不想创建任何视图或表 我需要它在飞行 – Nadeem

+0

伟大的答案肖恩,一如既往。 +1 – scsimon

+0

@NadeemZee你不必创建视图。你可以使用CTE。 – scsimon

0

首先建立一个日期表,你可以加入,然后再加入到表的东西,如:

[Date] BETWEEN [StartDate] AND DATEADD(day, [DaysCount], [StartDate]) 
1

这里是一个递归CTE的另一种方式,尽管肖恩·兰格答案肯定是首选的方法。

HERE IS A DEMO

declare @table table (StartDate date, DaysCount int) 
insert into @table 
values 
('20170623',1), 
('20170626',3), 
('20170807',1) 


declare @max date = (select max(StartDate) from @table) 

;with cte as(
    select min(StartDate) as StartDate 
    from @table 
    union all 
    select dateadd(day,1,StartDate) 
    from cte 
    where StartDate < @max 
) 


select 
    c.StartDate 
from 
cte c 
inner join 
@table t on 
    c.StartDate < dateadd(day,t.DaysCount,t.StartDate) 
    and c.StartDate >= t.StartDate 
option (maxrecursion 0) 
+0

不工作的查询来检查这个 ( '20170623',1), ( '20170626',3), ( '20170807',1), ( '20170926',4) – Nadeem

+0

您的评论是没有意义的,但我在我的答案中提供了一个可重复的示例链接。我看不出你在做什么来造成问题。 http://rextester.com/IOZPTC82923 – scsimon

0

考虑到你是好与SQL游标

---Creating records 
with cte as(Select Cast('01-01-2000' as Date) as startDate,1 as countD 
union all 
Select Cast('02-01-2000' as Date) as startDate,3 as countD 
union all 
Select Cast('10-01-2000' as Date) as startDate,1 as countD) 
Select * into #Temp from cte; 

--Creating temp table to hold results 
create table #Result(
startDate Date, 
) 

--Using cursor to insert records 
DECLARE @startDate Date, 
@count int; 


DECLARE db_cursor CURSOR FOR 
SELECT startDate , countD 
FROM #Temp 

OPEN db_cursor 
FETCH NEXT FROM db_cursor INTO @startDate , @count 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    WHILE @count> 0 
     BEGIN 
     set @count = @count-1; 
     set @startDate = DATEADD(DAY, @count, cast (@startDate as date)); 
     INSERT INTO #Result 
     Select @startDate; 

     END 

    FETCH NEXT FROM db_cursor INTO @startDate , @count 
END 

CLOSE db_cursor 
DEALLOCATE db_cursor 

Select * from #Result