SQL Server: расчет диапазонов дат - PullRequest
3 голосов
/ 04 апреля 2011

Я пытаюсь получить диапазон дат с начала этого месяца (предыдущий год) до текущего дня (предыдущий год). Есть ли способ упростить этот код?

SELECT 'From the beginning of month to this day, previous year' AS Label,
       CONVERT (DATETIME, CAST (DATEPART(YY, GETDATE()) - 1 AS CHAR (4)) + CASE 
                                                                           WHEN DATEPART(MM, GETDATE()) < 10 THEN '-0' + CAST (DATEPART(MM, GETDATE()) AS CHAR (1)) ELSE '-' + CAST (DATEPART(MM, GETDATE()) AS CHAR (2)) 
                                                                           END + '-01') AS Begin_date,
       CONVERT (DATETIME, CAST (DATEPART(YY, GETDATE()) - 1 AS CHAR (4)) + CASE 
                                                                           WHEN DATEPART(MM, GETDATE()) < 10 THEN '-0' + CAST (DATEPART(MM, GETDATE()) AS CHAR (1)) ELSE '-' + CAST (DATEPART(MM, GETDATE()) AS CHAR (2)) 
                                                                           END + CASE 
                                                                                 WHEN DATEPART(DD, GETDATE()) < 10 THEN '-0' + CAST (DATEPART(DD, GETDATE()) AS CHAR (1)) ELSE '-' + CAST (DATEPART(DD, GETDATE()) AS CHAR (2)) 
                                                                                 END) AS End_date

Ответы [ 5 ]

9 голосов
/ 04 апреля 2011
SELECT  'Anything' as Label
        ,DATEADD(month, DATEDIFF(month, 0, GETDATE()), 0) as firstdaythismonth
        ,DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0) as today
        ,DATEADD(year, -1, DATEADD(month, DATEDIFF(month, 0, GETDATE()), 0)) as firstdaythismonth_lastyear
        ,DATEADD(year, -1, DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0)) as today_lastyear
5 голосов
/ 04 апреля 2011
SELECT 
     DATEADD(yy, -1, CONVERT(VARCHAR(25),
     DATEADD(dd,-(DAY(GETDATE())-1),GETDATE()),101)) AS Date_Value,
     'First Day of Current Month Of Last Year' AS Date_Type
UNION
SELECT 
     DATEADD(yy, -1, GETDATE()) AS TodayLastYear, 'Today Last Year'

Или, если вам нужны значения, а не описание

SELECT 
     DATEADD(yy, -1, CONVERT(VARCHAR(25),
     DATEADD(dd,-(DAY(GETDATE())-1),GETDATE()),101))
UNION
SELECT 
     DATEADD(yy, -1, GETDATE()) AS TodayLastYear

Вы используете DATEADD и указываете гг, чтобы вычесть годы. Просто используйте отрицательное значение.

Я также поделюсь набором общих функций даты, которые я использую. Просто создайте это как табличную функцию:

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go

CREATE FUNCTION [dbo].[udfCommonDates] (@date datetime)
RETURNS @t table (week_start datetime,
                  week_end datetime,
                  lastweek_start datetime,
                  lastweek_end datetime,
                  month_start datetime,
                  month_end datetime,
                  lastmonth_start datetime,
                  lastmonth_end datetime,
                  yesterday_start datetime,
                  yesterday_end datetime,
                  today_start datetime,
                  today_end datetime,
                  thisweek_monday_start datetime,
                  thisweek_monday_end datetime,
                  year_start datetime,
                  year_end datetime,
                  tomorrow_noon datetime,
                  today_noon datetime,
                  date_only datetime)
BEGIN
   INSERT @t
   SELECT
   dbo.get_week_start ( @date ) AS week_start,
   dbo.get_week_end   ( @date ) AS week_end,
   dbo.get_week_start ( DATEADD(d, -7, @date ) ) AS lastweek_start,
   dbo.get_week_end   ( DATEADD(d, -7, @date ) ) AS lastweek_end,
   dbo.get_month_start( @date ) AS month_start,
   dbo.get_month_end  ( @date ) AS month_end,
   dbo.get_month_start ( DATEADD(m,-1, @date) ) AS lastmonth_start,
   dbo.get_month_end  ( DATEADD(m,-1,@date) ) AS lastmonth_end,
   dbo.get_yesterday_start ( @date ) AS yesterday_start,
   dbo.get_yesterday_end ( @date ) AS yesterday_end,
   dbo.get_today_start (@date) AS today_start,
   dbo.get_today_end ( @date ) AS today_end,
   dbo.get_weekday_start(1,@date) AS thisweek_monday_start,
   dbo.get_weekday_end(1,@date) AS thisweek_monday_end,
   dbo.get_year_start(@date) AS year_start,
   dbo.get_year_end(@date) AS year_end,  
   dbo.get_tomorrow_noon(@date) AS TomorrowNoon,
   dbo.get_today_noon(@date) AS TodayNoon,
   dbo.get_date_only(@date) AS DateOnly
RETURN
END

Вот скалярные функции для них:

    CREATE FUNCTION [dbo].[get_date_only] (@date datetime)
    RETURNS datetime
    WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
    AS    
    BEGIN
        RETURN dateadd(day, DateDiff(day, 0, GetDate()), 0)
    END
    GO

CREATE FUNCTION [dbo].[get_month_end] (@date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS    
BEGIN
   RETURN dateadd(ms, -3, dateadd (m,datediff(m,0,
          dateadd(m,1,@date)),0))
END
GO

CREATE FUNCTION [dbo].[get_month_start] (@date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS    
BEGIN
   RETURN dateadd(m,datediff(m,0, @date),0)
   END
GO

CREATE FUNCTION [dbo].[get_today_end] (@today datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS    
BEGIN
   return dateadd(ms, -3, datediff(d,0,dateadd(d,1,@today)))
END
GO

CREATE FUNCTION [dbo].[get_today_noon](@date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS    BEGIN
   RETURN DATEADD(hh, 12, DATEADD(d,DATEDIFF(d,0, @date),0))
END
GO

CREATE FUNCTION [dbo].[get_today_start] (@today datetime)
RETURNS datetime 
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS    BEGIN
   return dateadd(day, 0, datediff(d,0,@today))
END
GO

CREATE FUNCTION [dbo].[get_tomorrow_noon](@date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS    BEGIN
   RETURN DATEADD(hh, 12, DATEADD(d,DATEDIFF(d,-1, @date),0))
END
GO

CREATE FUNCTION [dbo].[get_week_end] (@date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS    BEGIN
   return dateadd(yyyy, datepart(yyyy,
      dateadd(weekday,7-datepart(weekday, @date),@date))-1900, 0)
    + dateadd(ms, -3,
      dateadd(dy, datepart(dy,
     dateadd(weekday,7-datepart(weekday, @date),@date)),0) )
END
GO

CREATE FUNCTION [dbo].[get_week_start] (@date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS    BEGIN
   return dateadd(yyyy, datepart(yyyy,
      dateadd(weekday,1-datepart(weekday, @date),@date))-1900, 0)
    + dateadd(dy, datepart(dy,
      dateadd(weekday,1-datepart(weekday, @date),@date))-1,0)
END
GO

CREATE FUNCTION [dbo].[get_weekday_end] (@weekday tinyint,
                                 @date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS    BEGIN
   return dateadd(yyyy, datepart(yyyy,
      dateadd(weekday,@weekday-
      datepart(weekday, @date),@date))-1900, 0)
    + dateadd(ms, -3,
      dateadd(dy, datepart(dy,
      dateadd(weekday,@weekday-datepart(weekday, @date),
                                        @date)),0) )
END
GO

CREATE FUNCTION [dbo].[get_weekday_start] (@weekday tinyint,
                                   @date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS    BEGIN
   return dateadd(yyyy, datepart(yyyy,
      dateadd(weekday,@weekday-
      datepart(weekday, @date),@date))-1900, 0)
    + dateadd(dy, datepart(dy,
      dateadd(weekday,@weekday-datepart(weekday, @date),
                                        @date))-1,0)
END
GO

CREATE FUNCTION [dbo].[get_year_end] (@date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS    BEGIN
RETURN DATEADD(year, DATEDIFF(year, 0, GetDate())+1, 0)-1
END
GO

CREATE FUNCTION [dbo].[get_year_start] (@date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS    BEGIN
   RETURN DATEADD(year,DATEDIFF(year,0, @date),0)
END
GO

CREATE FUNCTION [dbo].[get_yesterday_end] (@today datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS    BEGIN
   return dateadd(ms, -3, datediff(d,0,@today))
END
GO

CREATE FUNCTION [dbo].[get_yesterday_start] (@today datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS    BEGIN
   RETURN dateadd(day, -1, datediff(d,0,@today))
END
GO

Это было очень полезно для меня, потому что я использовал это в службах отчетов для параметров даты. Вы можете просто создать набор данных, ссылающийся на эту табличную функцию, а затем использовать их в параметрах для любой даты и времени в RS.

Вы можете выполнить всю эту табличную функцию следующим образом:

SELECT * FROM [MyDB]. [Dbo]. [UdfCommonDates] (GetDate ())

Результат примерно такой

enter image description here

Для пользователей служб отчетов

Теперь я уже упоминал ранее, что использую их для служб отчетов. Теперь ребята из RS могут подумать, но как это поможет мне, так как мне нужен набор данных и набор данных, которые могут быть основаны только на хранимой процедуре или прямой таблице. Без проблем создайте следующую хранимую процедуру:

CREATE PROCEDURE [dbo].[uspCommonDates] AS
begin
   set datefirst 1
   declare @date datetime
   set @date = getdate()
   select * from dbo.udfCommonDates(@date)
end

Теперь у вас есть хранимая процедура для использования в качестве набора данных ... Теперь в службах отчетов добавьте новый набор данных:

enter image description here

Теперь перейдите в раздел параметров отчета:

enter image description here

Теперь выберите этот набор данных dsFunctions (или как вы его называли), а затем выберите любое из полей значений из скалярных функций, таких как:

enter image description here

Теперь, когда вы запускаете отчет, он использует скаляры:

enter image description here

2 голосов
/ 04 апреля 2011

Вы можете использовать функции DATEADD, чтобы помочь:

 SELECT 'From the beginning of month to this day, previous year' AS Label,
DATEADD(YY,-1,DATEADD(DD,-(day(getdate())-1),DATEDIFF(dd, 0, GETDATE()))) AS Begin_date,
DATEADD(YY,-1,DATEDIFF(dd, 0, GETDATE()))  AS End_date
1 голос
/ 04 апреля 2011
SELECT  'From the beginning of month to this day, previous year' AS Label,
        CONVERT(DATETIME,LEFT(CONVERT(VARCHAR(6),DATEADD(YEAR,-1,GETDATE()),112),6)+'01') Begin_date,
        DATEADD(YEAR,-1,GETDATE()) End_date
1 голос
/ 04 апреля 2011

Для 2010-04-01, 2010-04-04 как насчет;

SELECT 
CAST(DATEADD(DAY, -365 + -(DAY(GETDATE())-1), GETDATE()) AS DATE), 
CAST(DATEADD(YEAR, -1, GETDATE()) AS DATE)  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...