【问题标题】:Get start- enddates of periods based on periodtype根据 periodtype 获取期间的开始日期
【发布时间】:2020-12-21 15:00:30
【问题描述】:

我有以下疑问:

declare @onlyrecents2 as int = 1
declare @periodtype2 as nvarchar(15) = 'w'
declare @last_modified_date_date2 as datetime2 = '2020-1-21 14:15:52.430'
declare @last_wanted_date_date2 as datetime2 = '2020-5-21 14:15:52.430'

select
IIF(@periodtype2 = 'w', iif(datediff(week,@last_modified_date_date2, @last_wanted_date_date2)>1,1,0),
IIF(@periodtype2 = 'm', iif(datediff(month,@last_modified_date_date2, @last_wanted_date_date2)>1,1,0),
IIF(@periodtype2 = 'q', iif(datediff(quarter,@last_modified_date_date2, @last_wanted_date_date2)>1,1,0),
IIF(@periodtype2 = 'y', iif(datediff(year,@last_modified_date_date2, @last_wanted_date_date2)>1,1,0),
IIF(@periodtype2 = 'c',0,0)))))
 as loop_needed
,IIF(@periodtype2 = 'w', datediff(week,@last_modified_date_date2, @last_wanted_date_date2),
IIF(@periodtype2 = 'm', datediff(month,@last_modified_date_date2, @last_wanted_date_date2),
IIF(@periodtype2 = 'q', datediff(quarter,@last_modified_date_date2, @last_wanted_date_date2),
IIF(@periodtype2 = 'y', datediff(year,@last_modified_date_date2, @last_wanted_date_date2),
IIF(@periodtype2 = 'c',0,0)))))as nr_loops_needed

它告诉我,如果我需要修改日期在“2020-1-21 14:15:52.430”和“2020-5-21 14:15:52.430”之间的记录,并且我想每周检索它们我需要 17 个循环。

现在我想要一个在 17 个循环中拆分 '2020-1-21 14:15:52.430''2020-5-21 14:15:52.430' 之间的日期范围的查询:

loop start end
1 2020-1-21 14:15:52.430 2020-1-28 14:15:52.430
2 2020-2-4 14:15:52.430 2020-2-11 14:15:52.430
...
17 startdate endddate

我知道可以做到,我以前做过,但看在上帝的份上,我不记得是怎么做到的.....

编辑:要清楚,我只需要知道如何根据参数@periodtype2 将日期范围从@last_modified_date_date2 拆分为周、月、季度、年的“@last_wanted_date_date2”

【问题讨论】:

  • 样本数据和期望的结果将使这个问题更加清晰。 CASE 要简单得多,为什么还要使用嵌套的 IIF()
  • Gordon,我觉得 IIF 更简单,我认为是口味问题。样本数据是什么意思?我只需要知道如何根据参数将日期范围从 '2020-1-21 14:15:52.430' 拆分为 '2020-5-21 14:15:52.430' 周、月、季度、年@periodtype2
  • 。 .在我看来,有一种观点认为,用于“if”功能的非标准 SQL 扩展比case 更简单——当然打字少了一点——尽管我不同意这种观点。但是对于嵌套的条件语句,我觉得很明显case更简单。
  • 您对 20200131 到 20200331 的月度有何预期结果? 20200231有问题吗?您真的要包括时间而不是午夜吗?
  • @GordonLinoff 我会检查这个案例的 CASE 声明

标签: sql sql-server tsql azure-sql-database


【解决方案1】:

这是一种方法,将所有单位转换为天(例如)并使用 cte 循环从 startdate 到 enddate:

DECLARE @datepart AS NVARCHAR(15) = N'year';
DECLARE @startDate AS DATETIME2 = '2020-1-21 14:15:52.430';
DECLARE @enddate AS DATETIME2 = '2020-5-21 14:15:52.430';
DECLARE @diffDays INT;

SET @diffDays = CASE @datepart
                    WHEN 'week' THEN 7
                    WHEN 'day' THEN 1
                    WHEN 'quarter' THEN 91
                    WHEN 'year' THEN 365
                    ELSE 1
                END;
WITH cte
AS
    (
        SELECT
            @startDate AS startdate
            , CASE WHEN DATEADD(DAY, @diffDays, @startDate) > @enddate 
                  THEN @enddate
                  ELSE DATEADD(DAY, @diffDays, @startDate)
              END      AS enddate
        UNION ALL
        SELECT
            cte.enddate
            , CASE WHEN DATEADD(DAY, @diffDays, cte.enddate) > @enddate 
                  THEN @enddate
                  ELSE DATEADD(DAY, @diffDays, cte.enddate)
              END AS enddate
        FROM
            cte
        WHERE
            cte.enddate < @enddate
    )
SELECT * FROM cte;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多