您好我正在尝试运行一个查询,以便为我拥有的每个项目在两个日期之间的每个月返回一行。参见示例数据:
<h1 class="x">
<span class="y">Here's a header</span>
</h1>
<div class="z">Here's some more text with a different format</div>
需要的最终数据:
Project Start End
1 1/1/2015 3/1/2015
2 2/1/2015 4/1/2015
我有几个项目,需要一个查询来同时为所有这些项目执行此操作。我该如何在SQL Server中执行此操作?
答案 0 :(得分:1)
如果你有或为Months创建一个表,这很简单:
create table dbo.Months([Month] date primary key);
declare @StartDate date = '20100101'
,@NumberOfYears int = 30;
insert dbo.Months([Month],MonthEnd)
select top (12*@NumberOfYears)
[Month] = dateadd(month, row_number() over (order by number) -1, @StartDate)
from master.dbo.spt_values;
如果您真的不想拥有Months表,可以像这样使用cte
:
declare @StartDate date = '20100101'
,@NumberOfYears int = 10;
;with Months as (
select top (12*@NumberOfYears)
[Month] = dateadd(month, row_number() over (order by number) -1, @StartDate)
from master.dbo.spt_values
)
然后像这样查询:
select
t.Project
, m.Month
from t
inner join dbo.Months m
on m.Month >= t.Start
and m.Month <= t.[End]
rextester演示:http://rextester.com/SXPX26360
返回:
+---------+------------+
| Project | Month |
+---------+------------+
| 1 | 2015-01-01 |
| 1 | 2015-02-01 |
| 1 | 2015-03-01 |
| 2 | 2015-02-01 |
| 2 | 2015-03-01 |
| 2 | 2015-04-01 |
+---------+------------+
日历和数字表参考:
答案 1 :(得分:1)
我个人喜欢这种东西的计数表。这是t-sql的瑞士军刀。
我为此在系统上创建了一个视图。如果您不想创建视图,只要需要计数表,就可以轻松使用这些ctes。
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
GO
现在我们只需要在表格中提供您的样本数据。
创建表#Projects ( 项目int ,开始日期时间 ,EndDate datetime )
插入#Projects 选择1,'1/1/2015','3/1/2015'联合所有 选择2,'2/1/2015','4/1/2015'
此时我们在这里找到了真正的问题,即检索您的信息。使用示例数据和视图,这变得非常简单。
select p.*
, NewMonth = DATEADD(MONTH, t.N - 1, p.Start)
from #Projects p
join cteTally t on t.N <= DATEDIFF(MONTH, p.Start, p.EndDate) + 1
order by p.Project
, t.N
答案 2 :(得分:1)
另一个选项是带有临时计数表的CROSS APPLY
Select A.Project
,Month = B.D
From YourTable A
Cross Apply (
Select Top (DateDiff(MONTH,A.Start,A.[End])+1) D=DateAdd(Month,-1+Row_Number() Over (Order By(Select null)),A.Start)
From master..spt_values
) B
返回
Project Month
1 2015-01-01
1 2015-02-01
1 2015-03-01
2 2015-02-01
2 2015-03-01
2 2015-04-01
答案 3 :(得分:0)
生成时间series从链接中获取帮助。
然后在
之间加入时间选择 - 某事 FROM table1 a / 类型 / JOIN table2 b ON b.field2 BETWEEN a.field2 AND a.field3