有没有办法简化此脚本,以便CASE语句不重复?在这个缩短的例子中它看起来可以接受,但实际上CASE语句要长得多,因为我有“每2周”,每4周一次“,”每月“等等。我正在使用SQL Server和WHILE声明来表现理由:CTE或MERGE会帮忙吗?
DECLARE @theStartDate DATE
DECLARE @Interval INT
DECLARE @eventCharges TABLE
(
[EventDate] [datetime],
Person_Id int
)
SET @today = GETDATE()
SET @Interval = 0
-- delete event charges from previous user
DELETE FROM @eventCharges
-- Insert the calculated transactions
WHILE @Interval < 100
BEGIN
SET @Interval = @Interval + 1
INSERT INTO @eventCharges
SELECT
CASE
WHEN pcc.Recurrence = 'Daily'
THEN DATEADD(DAY, @Interval, @theStartDate)
WHEN pcc.Recurrence = 'Weekly'
THEN DATEADD(WEEK, @Interval, @theStartDate)
END AS EventDate
,pcc.Person_Id
FROM @personChargeCurrent pcc
WHERE CASE
WHEN pcc.Recurrence = 'Daily'
THEN DATEADD(DAY, @Interval, @theStartDate)
WHEN pcc.Recurrence = 'Weekly'
THEN DATEADD(WEEK, @Interval, @theStartDate)
END <= @today
AND NOT EXISTS(SELECT 1 FROM dbo.PersonChargeTransaction pct
WHERE pct.Person_Id = pcc.Person_Id
AND pct.PersonCharge_Id = pcc.Id
AND pct.TransactionDate =
CASE
WHEN pcc.Recurrence = 'Daily'
THEN DATEADD(DAY, @Interval, @theStartDate)
WHEN pcc.Recurrence = 'Weekly'
THEN DATEADD(WEEK, @Interval, @theStartDate)
END)
ORDER BY StartDate
END
答案 0 :(得分:2)
您可以将其包装在一个函数中:
Create Function dbo.IntervalEnd(
@recurrence varchar(10),
@interval int,
@startDate date -- or whatever data type you're using for dates
) returns date as
begin
return case
when @recurrence = 'Daily' then dateadd(day, @interval, @startDate)
when @recurrence = 'Weekly' then dateadd(week, @interval, @startDate)
end
end
然后
Insert Into @eventCharges
Select
dbo.IntervalEnd(pcc.Recurrence, @Interval, @theStartDate) as EventDate,
pcc.Person_Id
From
@personChargeCurrent pcc
Where
dbo.IntervalEnd(pcc.Recurrence, @Interval, @theStartDate) <= @today And
Not Exists (
Select
1
From
dbo.PersonChargeTransaction pct
Where
pct.Person_Id = pcc.Person_Id And
pct.PersonCharge_Id = pcc.Id And
pct.TransactionDate
= dbo.IntervalEnd(pcc.Recurrence, @Interval, @theStartDate)
)
使用函数有开销。你必须决定稍微降低的性能是否值得权衡,以提高可读性。
答案 1 :(得分:1)
是的,CTE应该有所帮助。尝试将INSERT语句更改为:
WITH cte as
(SELECT CASE
WHEN Recurrence = 'Daily'
THEN DATEADD(DAY, @Interval, @theStartDate)
WHEN Recurrence = 'Weekly'
THEN DATEADD(WEEK, @Interval, @theStartDate)
END AS EventDate,
p.*
FROM @personChargeCurrent p)
INSERT INTO @eventCharges
SELECT cte.EventDate, cte.Person_Id
FROM cte
WHERE cte.EventDate <= @today AND
NOT EXISTS
(SELECT 1
FROM dbo.PersonChargeTransaction pct
WHERE pct.Person_Id = cte.Person_Id AND
pct.PersonCharge_Id = cte.Id AND
pct.TransactionDate = cte.EventDate)
ORDER BY StartDate
答案 2 :(得分:0)
您可以创建一个临时表,在其中插入计算字段,然后将该表与连接一起使用以插入数据/应用条件