提问人:Carbine734 提问时间:8/29/2023 最后编辑:marc_sCarbine734 更新时间:8/29/2023 访问量:88
将 Case 语句创建为函数
Create Case statement as Function
问:
我有一个列中的日期范围表,并分配为第 3 列。PeriodRanges
StartDate
EndDate
Period
例如:
开始日期 | 结束日期 | 时期 |
---|---|---|
'2023-01-01' | '2023-01-28' | 1 |
'2023-01-29' | '2023-02-25' | 2 |
然后,我有多个交易表,每个交易表都有一个日期 (entry_date) 数据点。我目前的解决方案是为每个期间创建一个案例陈述,并检查日期是否在这些范围之间并分配期间标签;但是,我的偏好是维护一个日期范围表,并检查日期是否介于 StartDate 和 EndDate 之间并返回相应的时间段,或者创建一个分配周期的函数。
日期“2023-01-05”可能有 10 个条目应全部返回周期 1,然后在日期“2023-02-05”上有 100 个条目应全部返回周期 2,以此类推作为查询的附加列
我尝试修复:
CASE
WHEN dbo.glentry.Entry_date BETWEEN '2023-01-01' AND '2023-01-28' THEN 'P1'
WHEN dbo.glentry.Entry_date BETWEEN '2023-01-29' AND '2023-02-25' THEN 'P2'
WHEN dbo.glentry.Entry_date BETWEEN '2023-02-26' AND '2023-03-25' THEN 'P3'
WHEN dbo.glentry.Entry_date BETWEEN '2023-03-26' AND '2023-04-22' THEN 'P4'
WHEN dbo.glentry.Entry_date BETWEEN '2023-04-23' AND '2023-05-20' THEN 'P5'
WHEN dbo.glentry.Entry_date BETWEEN '2023-05-21' AND '2023-06-17' THEN 'P6'
WHEN dbo.glentry.Entry_date BETWEEN '2023-06-18' AND '2023-07-15' THEN 'P7'
WHEN dbo.glentry.Entry_date BETWEEN '2023-07-16' AND '2023-08-12' THEN 'P8'
WHEN dbo.glentry.Entry_date BETWEEN '2023-08-13' AND '2023-09-09' THEN 'P9'
WHEN dbo.glentry.Entry_date BETWEEN '2023-09-10' AND '2023-10-07' THEN 'P10'
WHEN dbo.glentry.Entry_date BETWEEN '2023-10-08' AND '2023-11-04' THEN 'P11'
WHEN dbo.glentry.Entry_date BETWEEN '2023-11-05' AND '2023-12-02' THEN 'P12'
WHEN dbo.glentry.Entry_date BETWEEN '2023-12-02' AND '2023-12-31' THEN 'P13'
ELSE 'Non-2023'
END AS 'Period'
这是我目前的解决方案,但我讨厌在每个查询中插入它。我更希望将其放在表中并使用单个 case 语句或调用函数。
也尝试过这个,但我肯定知道这是不正确的,我不确定如何解决:
CREATE FUNCTION dbo.fn_ConvertDateToPeriod
(@Date DATETIME)
RETURNS VARCHAR(20)
AS
BEGIN
DECLARE @Period as VARCHAR(20)
SELECT @Period =
(CASE
WHEN @Date BETWEEN dbo.PeriodRanges.[StartDate] AND dbo.PeriodRanges.[EndDate] THEN dbo.PeriodRanges.[Period]
END)
FROM dbo.PeriodRanges
RETURN @Period
END
我的理想情况是简单地调用查询的 select 语句中的函数,例如:
SELECT
dbo.fn_ConvertDateToPeriod (dbo.Glentry.Entry_Date),
etc
etc
答:
1赞
eshirvana
8/29/2023
#1
似乎您想用您的:PeriodRanges
select pr.Period , g.*
from dbo.Glentry g
join dbo.PeriodRanges pr
on g.Entry_Date between pr.[StartDate] AND pr.[EndDate]
0赞
Sam
8/29/2023
#2
正如许多评论所建议的那样,您可以创建一个日期参考表,您可以在其中预先定义您的周期范围。
CREATE TABLE Date_reference(Start_Date date, End_Date date, Period varchar(5));
INSERT INTO Date_reference VALUES
('2023-01-01','2023-01-28','P1'),
('2023-01-29','2023-02-25','P2'),
('2023-02-26','2023-03-25','P3'),
('2023-03-26','2023-04-22','P4');...
然后将此参考表与主表连接起来,以获得所需的输出。
SELECT
a.*
,b.Period
FROM glentry a
LEFT JOIN Date_reference b
ON (a.Entry_date >= b.Start_Date) AND (a.Entry_date < b.End_Date)
这样就无需在每次使用函数执行相同操作时扫描列。
评论
3赞
marc_s
8/29/2023
ntext
数据类型将在 SQL Server 的未来版本中删除。避免在新的开发工作中使用这些数据类型,并计划修改当前使用它们的应用程序。改用 或。详情请见此处text
nvarchar(max)
varchar(max)
2赞
Dale K
8/29/2023
对于 2 个字符的字符串,几乎不需要进一步max
0赞
Sam
8/29/2023
谢谢你的建议。我把它作为一个例子发布。尽管如此,还是编辑为使用 varchar
0赞
Amit Mohanty
8/29/2023
#3
下面介绍如何创建函数并在查询中使用它:
CREATE FUNCTION dbo.fn_ConvertDateToPeriod
(@Date DATETIME)
RETURNS VARCHAR(20)
AS
BEGIN
DECLARE @Period INT
SELECT @Period = MIN(Period)
FROM PeriodRanges
WHERE @Date BETWEEN StartDate AND EndDate
RETURN CONCAT('P', CAST(@Period AS VARCHAR))
END
现在,您可以在 SELECT 语句中使用此函数:
SELECT
dbo.fn_ConvertDateToPeriod(dbo.Glentry.Entry_Date) AS 'Period',
-- Other columns you need
FROM
dbo.Glentry
评论