获取上周五和 4 周前上周五的 SSIS 表达式

SSIS expression for getting last friday and last friday 4 weeks ago

我正在寻找在 SSIS 中使用的表达式,以获取 4 周前的最新星期五和最后一个星期五。

我得到了这个:

DATEPART( "dw", GETDATE() ) == 2 ? GETDATE() : DATEADD( "day", -( DATEPART( "dw", GETDATE() ) +1), GETDATE() )

但我不确定它是否会在下周正常工作,例如,我不知道如何在 4 个星期五之前使用它(我尝试添加 28,但这似乎并没有成功)

好的,这里有两种方法,我认为最简单的一种是将其放在写入变量的脚本任务中。第二种是将 SQL 代码嵌入到 SQL 脚本中,并将结果提取到结果集中。如果您将它用作另一个数据流的输入,则第二个可能值得探索,但我将专注于第一个,因为它更容易(至少对我而言)。就这样吧。

方法一:

步骤 1) 从 2 个变量开始,均为 DateTime 类型。我将我的命名为 User::varLastFriday 和 User::var4FriAgo,但您可以随意命名。请记住,与大多数 SQL 和 Visual Studio 不同,这些区分大小写!

步骤 2) 创建 "Script Task"。请注意,有许多类似的声音任务,这是描述为 "Performs functions that are not provided by the standard Integration Services tasks. ..."

的任务

步骤 3) 编辑您的脚本,将 "Language" 设置为 Microsoft Visual Basic(要使用我的示例,如果您更舒服的话,您可以在 C 中做同样的事情)无论您的编辑器是哪一年,我使用的是 2015,但这在其他版本中应该是相似的,2008 至少是相同的。

第 4 步)仍在脚本属性中,下拉 "Read/Write variables" 并检查您的两个变量,如果未在此处选择它们,则无法更新它们。

步骤 5) 仍然在脚本属性中,单击显示 "Edit Script" 的按钮,它将打开一个带有框架项目的 Visual Studio window。您将修改 "Main" 过程中的代码。这是代码。请注意 Main 的声明和 return 值应该已经存在,您只是在我的 "Start/End of my custom code" 评论

之间插入我所拥有的内容
Public Sub Main()

      'Start of my custom code
      Dim nDayOfWeek As Integer = DatePart(DateInterval.Weekday, Now)
      Dim nOffset As Integer = 0
      If nDayOfWeek >= 6 Then
         nOffset = 6 - nDayOfWeek
      Else
         nOffset = -1 - nDayOfWeek
      End If
      Dts.Variables("User::varLastFriday").Value = DateAdd(DateInterval.Day, nOffset, Now)
      Dts.Variables("User::var4FriAgo").Value = DateAdd(DateInterval.Day, nOffset - 28, Now)
      'End of my custom code

      Dts.TaskResult = ScriptResults.Success
    End Sub

第 6 步) 保存脚本,保存任务,并将任务连接到您的其他步骤,因此它 运行 是第一个。它很快,但你不想要竞争条件

就是这样,当您 运行 它时,它会分别使用上周五和 4 周前周五的日期更新两个变量。

方法二: 逻辑可以写在 SQL 中并放在 "Execute SQL Task" 中,您可以在其中从结果集中获取结果。我很难让这个方法起作用,我通常可以 fiddle 足够让它最终起作用,但如果你想走那条路,你最好从其他人那里获得帮助。不过,这是生成日期的代码,它至少会给你一个开始。

--DECLARE @TestDate DATE = '2019-08-21' 
DECLARE @TestDate DATE = GETDATE() 
--08-23 is Friday, WEEKDAY 6, 25 is Sunday Weekday 1
--use GETDATE for today
DECLARE @LastFri DATE 
-- >=6 means running on Friday returns today, 
--use >6 if you want running on Friday to return last friday
SET @LastFri = DATEADD(day, IIF(DATEPART(WEEKDAY, @TestDate) >= 6 
    ,6-DATEPART(WEEKDAY, @TestDate)
    ,-1-DATEPART(WEEKDAY, @TestDate)),@TestDate)
SELECT @TestDate as IfDayIs , @LastFri as ThenLastFriIs, DATEADD(day, -28, @LastFri ) as Fri4Ago

--Fridays in August: 30, 23, 16, 9, 2 July: 26, 19, 12

您可以使用 SQL 脚本来做同样的事情。将执行 SQL 任务添加到您的流程中。创建一个对象类型变量,因为您将需要它来存储两个日期。

然后,如果您 运行 下面的脚本,它将为您提供上周五和 4 周前的周五。 (您可以通过更改天数值来选择任意周数之前的星期五)

(
  SELECT getdate() DateValue
  UNION ALL
  SELECT  DateValue - 1
  FROM    mycte   
  WHERE   DateValue - 1 > DATEADD(day,-34, GETDATE())
)                                                                                           
select DateValue from (
SELECT  DateValue,DATEPART(DW, DateValue) as weekday,ROW_NUMBER() over (order by datevalue desc) as Most_Recent_Friday
FROM    mycte
where DATEPART(DW, DateValue) = 6                                                        ) a where Most_Recent_Friday in (1,5)
OPTION (MAXRECURSION 0)

原始结果为:

DateValue                       |  weekday    |   Most_Recent_Friday
2019-08-16 09:46:25.330         |  6          |   1
2019-08-09 09:46:25.330         |  6          |   2
2019-08-02 09:46:25.330         |  6          |   3
2019-07-26 09:46:25.330         |  6          |   4
2019-07-19 09:46:25.330         |  6          |   5  

我从中选择了第 1 个星期五(最近)和第 5 个星期五(4 周前),您可以选择作为您的要求

您将从给定的查询中获得以下输出:

2019-08-16 09:46:25.330
2019-07-19 09:46:25.330

上周五将是 Most_Recent_Friday = 1,而 4 周前的周五将是 Most_Recent_Friday = 5 或者可能是 4,无论您需要什么都可以。您可以将结果存储在创建的对象变量中,并在您的流程中使用它