我正在尝试为SSRS报告编写TSQL脚本,该报告使用CTE根据所选参数选择记录。我正在寻找最有效的方法来做到这一点,无论是在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,那么我可能不需要按任何字段进行分区,因为我只想通过actual_date降序排序前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还是特定值?
答案 0 :(得分:1)
无论你想以什么方式实现,在'null'或'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)