1

我正在尝试为使用 CTE 根据所选参数选择记录的 SSRS 报告编写 TSQL 脚本。我正在寻找最有效的方法来做到这一点,无论是在 TSQL 和/或 SSRS 中。我有 4 个参数可以设置为 NULL(所有值)或一个特定值。然后在我的 CTE 中,我有以下行:

    ROW_NUMBER() over(partition by G.[program_providing_service],G.people_id
    order by G.[actual_date] desc) as rowID

上面的 CTE 适用于 Program 为 NULL 且 People 不为 null 的情况。我的4个参数是:

计划、设施、员工和人员。

所以我只想在它们为 NULL 时对值进行分区。目前,我根据参数值通过一个 CTE 来实现这一点。例如,如果他们为除 People 之外的所有参数选择 NULL,则此 CTE 将如下所示:

    ROW_NUMBER() over(partition by G.people_id
    order by G.[actual_date] desc) as rowID

或者如果所有 5 个参数都为空:

    ROW_NUMBER() over(partition by G.[program_providing_service], G.[site_providing_service], G.staff_id, G.people_id
    order by G.[actual_date] desc) as rowID

如果他们没有为 4 个参数中的任何一个选择 NULL,那么我可能不需要按任何字段进行分区,因为我只想要按实际日期降序排序的前 1 条记录。这是我的 CTE 的样子:

;with cte as
(
Select    distinct
    G.[actual_date],
    G.[site_providing_service],
    p.[program_name],
    G.[staff_id],
    G.program_providing_service,
    ROW_NUMBER() over(partition by G.[program_providing_service],G.people_id
    order by G.[actual_date] desc) as rowID

From 
event_log_rv G With (NoLock)

WHERE 
...
AND (@ClientID Is Null OR [people_id]=@ClientID)
AND (@StaffID Is Null OR [staff_id] = @StaffID)
AND (@FacilityID Is Null OR [site_providing_service] = @FacilityID)
AND (@ProgramID Is Null OR [program_providing_service] = @ProgramID)
and (@SupervisorID is NULL OR staff_id in (select staff_id from #supervisors))
)
SELECT 
    [actual_date],
    [site_providing_service],
    [program_name],
    [staff_id],
    program_providing_service,
    people_id,
    rowID

FROM cte WHERE rowid = 1
ORDER BY [Client_FullName]

其中 ROW_NUMBER 行因所选参数而异。目前我在这个 TSQL 脚本中有 5 个 IF 语句,如下所示:

IF @ProgramID IS NOT NULL AND @ClientID IS NULL
BEGIN
...
END

with one CTE in each of these IF statements:

IF @FacilityID IS NOT NULL AND @ClientID IS NULL
BEGIN
...

END

IF @ProgramID IS NOT NULL AND @ClientID IS NULL
BEGIN
...
END

IF @StaffID IS NOT NULL AND @ClientID IS NULL
BEGIN
...

END

IF @ClientID IS NOT NULL
BEGIN
...
END

我如何为所有可能的选项编码,无论他们选择 NULL 还是特定值?

4

1 回答 1

2

OMG....我花了很长时间才试图理解你想要做什么。你的描述有些矛盾。请修改您的描述。就像您说的那样,您只想在值为 NULL 时对值进行分区;然后您还说,当他们为除人员以外的所有参数选择 NULL 时,您就对人员进行分区....

不管你想实现什么方式,partition on 'null' or 'not null',都可以通过构造动态sql来实现,而不用加很多[if...else]

以下代码是伪代码,绝对未经测试。只是给你一个提示。以下代码有一个假设,即您的参数在分区顺序中具有优先级,例如,如果 Program 不为 null(或 null),则 Program 在第一个位置。

    declare @sql varchar(max)
    set @sql = '
    ;with cte as
    (
    Select    distinct
        G.[actual_date],
        G.[site_providing_service],
        p.[program_name],
        G.[staff_id],
        G.program_providing_service,
        ROW_NUMBER() over(partition by
    '
    if(@progarm is null)
       set @sql = @sql + 'G.[program_providing_service],'
    if(@facility is null) 
       set @sql = @sql + 'G.[site_providing_service],'
    if(@staff is null )
       set @sql = @sql + 'G.staff_id,'
    if(@people is null)
       set @sql = @sql + 'G.people_id'
    set @sql = @sql + '
        order by G.[actual_date] desc) as rowID
    From 
    event_log_rv G With (NoLock)
    WHERE 
    ...
    AND (@ClientID Is Null OR [people_id]=@ClientID)
    AND (@StaffID Is Null OR [staff_id] = @StaffID)
    AND (@FacilityID Is Null OR [site_providing_service] = @FacilityID)
    AND (@ProgramID Is Null OR [program_providing_service] = @ProgramID)
    and (@SupervisorID is NULL OR staff_id in (select staff_id from #supervisors))
    )
    SELECT 
        [actual_date],
        [site_providing_service],
        [program_name],
        [staff_id],
        program_providing_service,
        people_id,
        rowID
    FROM cte WHERE rowid = 1
    ORDER BY [Client_FullName]
    '
    exec(@sql)

于 2013-03-15T05:51:42.297 回答