mko*_*mko 1 t-sql user-defined-functions
我构建了我的sql表,如下所示:
ItemID Price MaxPeople CalculationUnit
1 10 4 people/item
2 70 2 item
3 30 8 week/item
4 50 2 week
Run Code Online (Sandbox Code Playgroud)
等等
现在我想运行一个类似的基本存储过程
sp_return_items_total
@Days as int,
@Items as int
AS
select itemid, price, total from table
Run Code Online (Sandbox Code Playgroud)
Total将是基于此计算的值(number of days * calculation unit * price).
例如,对于@Days = 5'@Items = 2',结果将是:
1, 10, 400 (10 * 4 people * 2 items * 5 days)
2, 70, 140 (70 * 1 * 2 items * 1)
3, 30, 42.85 (30 * 1 * 2 items * 5/7 days)
4, 50, 35.71 (50 * 1 * 1 items * 5/7 days)
Run Code Online (Sandbox Code Playgroud)
我试图找到一个解决方案,如何根据sp参数和计算单位获得总值.
感谢您的参与
编辑2/10/12:修改后的查询以对应修订的示例输出:
-- Set up the test data.
declare @AmalgamatedStuff as table ( ItemId int, Price int, MaxPeople int, CalculationUnit varchar(16) )
insert into @AmalgamatedStuff ( ItemId, Price, MaxPeople, CalculationUnit ) values
( 1, 10, 4, 'people/item' ),
( 2, 70, 2, 'item' ),
( 3, 30, 8, 'week/item' ),
( 4, 50, 2, 'week' )
-- Stored procedure parameters.
declare @Days as int = 5
declare @Items as int = 2
-- The query.
select ItemId, Price,
case CalculationUnit
when 'item' then Price * @Items
when 'people/item' then Price * MaxPeople * @Items * @Days
when 'week' then round( Price * @Days / 7.0, 2 )
when 'week/item' then round( Price * @Items * @Days / 7.0, 2 )
else NULL
end as Total
from @AmalgamatedStuff
Run Code Online (Sandbox Code Playgroud)
请注意,42.857142未能在第三行结果中舍入到42.85.
编辑:请记住,无法获得具有可变数量的列和未指定的计算的建议结果:
-- Set up the test data.
declare @AmalgamatedStuff as table ( ItemId int, Price int, MaxPeople int, CalculationUnit varchar(16) )
insert into @AmalgamatedStuff ( ItemId, Price, MaxPeople, CalculationUnit ) values
( 1, 10, 4, 'people/item' ),
( 2, 70, 2, 'item' ),
( 3, 30, 8, 'week/item' ),
( 4, 50, 2, 'week' )
-- Stored procedure parameters.
declare @Days as int = 5
declare @Items as int = 2
-- The query, give or take the correct calculations.
declare @SpuriousFactorToGetSuggestedResult as int = 2
select ItemId, Price,
case CalculationUnit
when 'item' then Price * @Items
when 'people/item' then Price * MaxPeople * @Items * @Days
when 'week' then Price * @Items * @Days / 7
when 'week/item' then Price * @Items * @Days * @SpuriousFactorToGetSuggestedResult / 7
else NULL
end as Total
from @AmalgamatedStuff
Run Code Online (Sandbox Code Playgroud)
实际上,将查询存入过存储过程仍然是OP的练习.
"设计"仍然在腐臭之下,并且越来越快地溃烂.
编辑:回答以前编辑的"问题"仍然如下:
您可以使用CASE来执行以下操作:
select ItemId, Price,
case
when CalculationUnit = 'day' then @Days * Price
when CalculationUnit = 'week' then @Days / 7 * Price
else NULL
end as 'Total'
from MyIllConceivedTable
Run Code Online (Sandbox Code Playgroud)
如前所述,这是一个糟糕的设计.
在某些情况下,拥有一个查找表可能是有意义的,例如,可以让您将各种度量单位映射到某个公共基础.考虑权重和它们的克当量.(也是存储全名"Ounces"和缩写"Oz"的便利位置,......)您的数据表将包含对单位表的引用.
在某些情况下,它可能与时间单位有关.预定事件可能每天,每周,每月,每季度和每年重复发生.单元的长度有些灵活,用途往往很奇特.(我在每个月的第3个星期三吃午饭.见到你了吗?)
关于性能,返回结果的计算也不错.您可以使用计算列或视图来实现(恶意)结束.当您为每一行调用函数时,性能会受到影响,例如,将DATETIME列转换为字符串的WHERE子句使用LIKE来确定字符串中是否存在"R".
无论你选择什么,请不要使用像daffy那样的东西:
declare @Today as Date
set @Today = SysDateTime()
select @Today,
DateDiff(day, @Today, DateAdd( "day", 1, @Today ) ) as 'Days in a Day',
DateDiff(day, @Today, DateAdd( "week", 1, @Today ) ) as 'Days in a Week',
DateDiff(day, @Today, DateAdd( "month", 1, @Today ) ) as 'Days in a Month' -- Sometimes!
Run Code Online (Sandbox Code Playgroud)