Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Количество дней в нескольких годах  [new]
minya13_85
Member

Откуда: Москва
Сообщений: 606
Microsoft SQL Server 2008 (SP3) - 10.0.5500.0 (X64)   Sep 21 2011 22:45:45   Copyright (c) 1988-2008 Microsoft Corporation  Enterprise Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1) 


Клиент выбирает несколько годов. нужно определить кол-во дней, вплоть до сегодняшнего.
DECLARE @Y nvarchar(50)
SET @Y='2008,2010,2013'


т.е. нужно получить на выходе кол-во дней за 2008 год+2010+ 2013 год до сегодняшнего момента..
19 фев 13, 17:05    [13950173]     Ответить | Цитировать Сообщить модератору
 Re: Количество дней в нескольких годах  [new]
Glory
Member

Откуда:
Сообщений: 104751
количество дней в году - это разница между первой датой года и последней
19 фев 13, 17:10    [13950223]     Ответить | Цитировать Сообщить модератору
 Re: Количество дней в нескольких годах  [new]
iap
Member

Откуда: Москва
Сообщений: 47145
Glory
количество дней в году - это разница между первой датой года и последней
плюс единица
Или разница между первыми датами года и года, следующего за ним.
19 фев 13, 17:32    [13950384]     Ответить | Цитировать Сообщить модератору
 Re: Количество дней в нескольких годах  [new]
iap
Member

Откуда: Москва
Сообщений: 47145
Например,
SELECT DATEDIFF(DAY,'2013','2014')
19 фев 13, 17:33    [13950390]     Ответить | Цитировать Сообщить модератору
 Re: Количество дней в нескольких годах  [new]
minya13_85
Member

Откуда: Москва
Сообщений: 606
года выбирают не по порядку.. и вводят их текстовым полем через запятую
Т.е. нужно сначала разбить на года, потом в каждом году вычислить период и просуммировать? Или как проще? Годов может быть сколько угодно..
19 фев 13, 17:44    [13950467]     Ответить | Цитировать Сообщить модератору
 Re: Количество дней в нескольких годах  [new]
Glory
Member

Откуда:
Сообщений: 104751
minya13_85
Т.е. нужно сначала разбить на года, потом в каждом году вычислить период и просуммировать? Или как проще?

Проще иметь сразу таблицу со всеми годами и количеством дней в них
19 фев 13, 17:47    [13950498]     Ответить | Цитировать Сообщить модератору
 Re: Количество дней в нескольких годах  [new]
iap
Member

Откуда: Москва
Сообщений: 47145
iap
Например,
SELECT DATEDIFF(DAY,'2013','2014')
Забыл - самое короткое выражение для количества дней в году:
SELECT 365+ISDATE('2013'+'0229');
19 фев 13, 20:05    [13951134]     Ответить | Цитировать Сообщить модератору
 Re: Количество дней в нескольких годах  [new]
pio777
Member

Откуда:
Сообщений: 127
create FUNCTION [dbo].[Split](@String varchar(MAX), @Delimiter char(1))       
returns @temptable TABLE (items varchar(MAX))       
as       
begin      
    declare @idx int       
    declare @slice varchar(8000)       

    select @idx = 1       
        if len(@String)<1 or @String is null  return       

    while @idx!= 0       
    begin       
        set @idx = charindex(@Delimiter,@String)       
        if @idx!=0       
            set @slice = left(@String,@idx - 1)       
        else       
            set @slice = @String       

        if(len(@slice)>0)  
            insert into @temptable(Items) values(@slice)       

        set @String = right(@String,len(@String) - @idx)       
        if len(@String) = 0 break       
    end   
return 
end;

go

DECLARE @Y nvarchar(50)
SET @Y='2008,2010,2013'
select sum(datediff(dd, cast(items as date), dateadd(yy, 1, cast(items as date))))  from [dbo].[Split](@Y, ',')
20 фев 13, 00:18    [13952167]     Ответить | Цитировать Сообщить модератору
 Re: Количество дней в нескольких годах  [new]
iap
Member

Откуда: Москва
Сообщений: 47145
DECLARE @Y nvarchar(50)=N'2008,2010,2013';
SELECT SUM(CASE Y WHEN YEAR(CURRENT_TIMESTAMP) THEN DATEPART(DAYOFYEAR,CURRENT_TIMESTAMP) ELSE 365+ISDATE(Y+N'0229') END) [CountOfDays]
FROM
(
 SELECT SUBSTRING(@Y,V.number,
  (
   SELECT MIN(VV.number)
   FROM master.dbo.spt_values VV
   WHERE VV.type='P' AND VV.number BETWEEN V.number AND LEN(@Y)+1
   AND CHARINDEX(SUBSTRING(@Y+N',',VV.number,1),N',')>0
  )-V.number
 )
 FROM master.dbo.spt_values V
 WHERE V.type='P' AND V.number BETWEEN 1 AND LEN(@Y)+1
 AND CHARINDEX(SUBSTRING(N','+@Y,V.number,1),N',')>0
)T(Y);

Функция, которая делит строку на слова
20 фев 13, 09:40    [13952946]     Ответить | Цитировать Сообщить модератору
 Re: Количество дней в нескольких годах  [new]
Cygapb-007
Member

Откуда:
Сообщений: 1677
DECLARE @Y nvarchar(50)='2008,2010,2013'
--select 366+365+datediff(dd,'20130101',getdate())
select sum(case year(getdate())when x.yr then datediff(dd,x.yr+'0101',getdate()) else 365+isdate(yr + '0229') end)days
from (select cast('<y>'+replace(@y,',','</y><y>')+'</y>' as xml)y)a
cross apply(
  select b.c.value('text()[1]','char(4)')yr
  from a.y.nodes('/y')b(c)
)x
20 фев 13, 10:08    [13953072]     Ответить | Цитировать Сообщить модератору
 Re: Количество дней в нескольких годах  [new]
pio777
Member

Откуда:
Сообщений: 127
iap, Cygapb-007,

Вас не смущает что 366+365+365=1096, а у вас 782 и 781 соответственно.
20 фев 13, 10:34    [13953180]     Ответить | Цитировать Сообщить модератору
 Re: Количество дней в нескольких годах  [new]
iap
Member

Откуда: Москва
Сообщений: 47145
pio777
iap, Cygapb-007,

Вас не смущает что 366+365+365=1096, а у вас 782 и 781 соответственно.
По условию в текущем году (2013) нужны не все дни, а только до сегодняшнего дня
20 фев 13, 10:36    [13953192]     Ответить | Цитировать Сообщить модератору
 Re: Количество дней в нескольких годах  [new]
pio777
Member

Откуда:
Сообщений: 127
iap,

Простите, не дочитал условие.
create FUNCTION [dbo].[Split](@String varchar(MAX), @Delimiter char(1))       
returns @temptable TABLE (items varchar(MAX))       
as       
begin      
    declare @idx int       
    declare @slice varchar(8000)       

    select @idx = 1       
        if len(@String)<1 or @String is null  return       

    while @idx!= 0       
    begin       
        set @idx = charindex(@Delimiter,@String)       
        if @idx!=0       
            set @slice = left(@String,@idx - 1)       
        else       
            set @slice = @String       

        if(len(@slice)>0)  
            insert into @temptable(Items) values(@slice)       

        set @String = right(@String,len(@String) - @idx)       
        if len(@String) = 0 break       
    end   
return 
end;

go

DECLARE @Y nvarchar(50)
SET @Y='2008,2010,2013'
select sum(
	case 
		when items != year(getdate()) then datediff(dd, cast(items as date), dateadd(yy, 1, cast(items as date)))
		else datediff(dd, cast(items as date), getdate())
	end)
from [dbo].[Split](@Y, ',')
20 фев 13, 11:11    [13953385]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить