在sql server中,我有一个表,其中包含作业发布的开始和结束日期。在给定用户一个月和一年的情况下,我需要找到该发布的给定年/月的开始日期和结束日期之间的天数。
因此,如果发布开始日期是2010/11/15,结束日期是2010/12/05 然后输出应该是:
November 16 days
December 5 days
Total 21 days
我一直用这个打我的头靠在墙上,而且我的想法很新鲜。
答案 0 :(得分:2)
答案 1 :(得分:2)
这可能是最简洁的答案。
declare @start datetime, @end datetime
select @start = '20101115', @end = '20101205'
select datename(month,@start+number), count(*)
from master..spt_values
where type='P'
and number between 0 and datediff(d,@start,@end)
group by datename(month,@start+number), convert(char(6),@start+number,112)
order by convert(char(6),@start+number,112)
它适用于最长2048天(7 - 8年)的范围,但如果您需要,可以延长更长时间(仅根据要求 - 看起来会更复杂)。
convert(char
部分的唯一原因是让11月在12月之前以及明年1月之前出现。
答案 2 :(得分:1)
编辑:另一个小修正或两个...
编辑给出完整答案......
declare @user_start_date datetime
set @user_start_date = '1/1/2011'
declare @user_end_date datetime
set @user_end_date = '1/10/2011'
declare @job_start_date datetime
set @job_start_date = '1/2/2011'
declare @job_end_date datetime
set @job_end_date = '1/11/2011'
declare @nextStartDate datetime;
set @nextStartDate = str(datepart(mm, @user_start_date)) + '/1/' + str(datepart(yyyy, @user_start_date))
declare @nextEndDate datetime;
set @nextEndDate = dateadd(dd,-1,dateadd(mm,1,@nextStartDate))
create table #monthYears(startDate datetime, endDate datetime)
while (@nextStartDate < @user_end_date) begin
insert into #monthYears values(@nextStartDate, @nextEndDate)
set @nextStartDate = dateadd(mm,1,@nextStartDate)
set @nextEndDate = dateadd(dd,-1,dateadd(mm,1,@nextStartDate))
end
-- Print Months
select [month], [year], case when dayCount < 0 then 0 else dayCount end from (
select month(startDate) month, year(startDate) year , datediff(dd,
case when startDate > @job_start_date then startDate else @job_start_date end,
case when endDate < @job_end_date then endDate else @job_end_date end) dayCount
from #monthYears) temp
select datediff(dd,
case when @user_start_date > @job_start_date then @user_start_date else @job_start_date end,
case when @user_end_date < @job_end_date then @user_end_date else @job_end_date end)
答案 3 :(得分:1)
这在SQL中有点难,但这会创建一个包含月份(整数)和天数的表格。
我会留给你将整数转换为月份并添加总数
SET NOCOUNT on
Declare @StartDate datetime
Declare @EndDate datetime
Declare @StartDateNormalized datetime
Declare @EndDateNormalized datetime
SET @StartDate = '2010/11/15'
SET @EndDate = '2011/2/05'
declare @result table ( month int, days int)
--Normalize the Inputs
SET @StartDateNormalized = cast(Month(@startDate) as varchar) + '/1/' + cast(year(@startDate) as varchar)
SET @EndDateNormalized = cast(Month(@EndDate) as varchar) + '/1/' + cast(year(@EndDate) as varchar)
insert into @result
values
( MONTH(@StartDateNormalized),
DateDiff(Day, @StartDate, DateAdd(month, 1, @StartDateNormalized ) )
)
SET @StartDateNormalized = DateAdd(month, 1, @StartDateNormalized )
WHILE (@StartDateNormalized < @EndDateNormalized)
BEGIN
insert into @result
values
( MONTH(@StartDateNormalized),
DateDiff(Day, @StartDateNormalized, DateAdd(month, 1, @StartDateNormalized ) )
)
SET @StartDateNormalized = DateAdd(month, 1, @StartDateNormalized )
END
insert into @result
values
( MONTH(@EndDateNormalized),
DateDiff(Day, @EndDateNormalized, @EndDate ) + 1
)
select * from @result
答案 4 :(得分:1)
DECLARE
@StartDate datetime,
@EndDate datetime;
SET @StartDate = '20101115';
SET @EndDate = '20101205';
WITH Mos AS (
SELECT
Number,
DateAdd(Month, Number, @StartDate - Day(@StartDate) + 1) MoDate
FROM master.dbo.spt_values
WHERE
Type = 'P'
AND Number <= DateDiff(Month, @StartDate, @EndDate)
), Dys AS (
SELECT
MoDate,
DateDiff(
Day,
CASE WHEN Number = 0 THEN @StartDate ELSE MoDate END,
CASE WHEN Number = DateDiff(Month, @StartDate, @EndDate) THEN @EndDate ELSE DateAdd(Month, 1, MoDate) - 1 END
) + 1 Cnt
FROM Mos
)
SELECT
Year(MoDate) Yr,
Coalesce(DateName(Month, MoDate), 'Total') Mo,
Convert(varchar(11), Sum(Cnt)) + ' day' + CASE WHEN Sum(Cnt) = 1 THEN '' ELSE 's' END Descr
FROM Dys
GROUP BY MoDate
WITH ROLLUP
ORDER BY Grouping(MoDate), MoDate;
这是一个表版本,以防你想同时使用多个版本:
CREATE TABLE AccountDates (
AccountCode varchar(10) NOT NULL CONSTRAINT PK_AccountDates PRIMARY KEY CLUSTERED,
StartDate datetime,
EndDate datetime
);
INSERT AccountDates VALUES ('BLINKEN', '20101115', '20101205');
INSERT AccountDates VALUES ('KRAM', '20101027', '20110118');
INSERT AccountDates VALUES ('NUVU', '20101207', '20101207');
WITH Mos AS (
SELECT
AccountCode,
D.StartDate,
D.EndDate,
Number,
DateAdd(Month, Number, D.StartDate - Day(D.StartDate) + 1) MoDate
FROM
AccountDates D
INNER JOIN master.dbo.spt_values V ON V.Number <= DateDiff(Month, D.StartDate, D.EndDate)
WHERE
V.Type = 'P'
), Dys AS (
SELECT
AccountCode,
MoDate,
DateDiff(
Day,
CASE WHEN Number = 0 THEN StartDate ELSE MoDate END,
CASE WHEN Number = DateDiff(Month, StartDate, EndDate) THEN EndDate ELSE DateAdd(Month, 1, MoDate) - 1 END
) + 1 Cnt
FROM Mos
)
SELECT
AccountCode,
Year(MoDate) Yr,
Coalesce(DateName(Month, MoDate), 'Total') Mo,
Convert(varchar(11), Sum(Cnt)) + ' day' + CASE WHEN Sum(Cnt) = 1 THEN '' ELSE 's' END Descr
FROM Dys
GROUP BY AccountCode, MoDate
WITH ROLLUP
HAVING Grouping(AccountCode) = 0
ORDER BY
AccountCode,
Grouping(MoDate),
MoDate;
我从原始查询中略微简化了一些事情。
答案 5 :(得分:0)
以下示例确定 当前之间的天数差异 日期和产品的订单日期 在AdventureWorks数据库中。
USE AdventureWorks;
GO
SELECT DATEDIFF(day, OrderDate, GETDATE()) AS NumberOfDays
FROM Sales.SalesOrderHeader;
GO
http://msdn.microsoft.com/en-us/library/ms189794%28v=sql.90%29.aspx