如何设计有特殊需求的表

snakefish 2017-12-01 05:44:09
目前在做一个绩效考核的项目,其中有一个计算绩效得分的公式:当某一个考核项完成率小于90%时,扣20分;大于90%小于等于100%时,每减少1%扣1分;大于100%小于110%时,每增加1%奖1分;大于等于110%时,每增加1%奖2分。
由于绩效考核的考核项每一年计算标准都会发生变化,因此想要保存到表中便于后期维护,但是在设计表的时候遇到了难题,想了一下午也没搞清楚这种类型的怎么设计。
...全文
122 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
snakefish 2017-12-02
  • 打赏
  • 举报
回复
引用 4 楼 yenange 的回复:
#3 的思路很好, 把我#2和他的思路结合一下:
USE tempdb
GO
IF OBJECT_ID('kh_main') IS NOT NULL DROP TABLE kh_main
GO
IF OBJECT_ID('kh_item') IS NOT NULL DROP TABLE kh_item
GO
--考核主要表,设置起始时间主要是为防止一年有多个考核标准
CREATE TABLE kh_main (
	mainId INT IDENTITY(1,1) PRIMARY KEY,
	[year] INT NOT NULL,			
	[beginTime] DATETIME NOT NULL,	
	endTime DATETIME NOT NULL
)
GO
CREATE TABLE kh_item(
	itemId INT IDENTITY(1,1),
	mainId INT NOT NULL,
	[case] VARCHAR(300) NOT NULL,
	beginPercent DECIMAL(10,2),
	endPercent DECIMAL(10,2),
	[funcPara] INT NOT NULL
)
INSERT INTO kh_main(
	[year],
	beginTime,
	endTime
)
VALUES
(
	2017,
	'2017-01-01',
	'2017-12-31 23:59:59'
)

--有2条记录我加了等于两个字(跟前后记录不同),业务上最好商定:标准可以随便变, 但起止包括或不包括端点要讲清楚而且前后必须一致!
--避免不必要的纷争, 当然, 这是小事,找领导商定下来就可以了。
INSERT INTO kh_item(mainId,	[case],beginPercent,endPercent,[funcPara]) VALUES(	1,'完成率小于(等于)90%时,扣20分',0,90,1)
INSERT INTO kh_item(mainId,	[case],beginPercent,endPercent,[funcPara]) VALUES(	1,'大于90%小于等于100%时,每减少1%扣1分',10,100,2)
INSERT INTO kh_item(mainId,	[case],beginPercent,endPercent,[funcPara]) VALUES(	1,'大于100%小于(等于)110%时,每增加1%奖1分',100,110,3)
INSERT INTO kh_item(mainId,	[case],beginPercent,endPercent,[funcPara]) VALUES(	1,'大于等于110%时,每增加1%奖2分',110,9999999,4)
GO
IF OBJECT_ID('Fun_Kh') IS NOT NULL DROP FUNCTION Fun_kh
GO
-- =============================================
-- Author:		yenange	
-- Create date: 2017-12-02
-- Description:	考核函数
-- =============================================
CREATE FUNCTION Fun_kh(
	@percent INT,
	@funPara INT
)
RETURNS DECIMAL(10,2)
AS
BEGIN
	DECLARE @r DECIMAL(10,2)
	IF @funPara=1
	BEGIN
		SET @r=@percent-20
	END
	ELSE IF @funPara=2
	BEGIN
		SET @r=@percent-(@percent-90)
	END
	ELSE IF @funPara=3
	BEGIN
		SET @r=@percent+(@percent-100)
	END
	ELSE IF @funPara=4
	BEGIN
		SET @r=@percent+(@percent-110)
	END
	RETURN @r
END
GO
--某个项目是 2017 年度内的, 完成率为 110%
DECLARE @year INT,@percent INT
SELECT @year=2017,@percent=105

SELECT b.funcPara,dbo.FUN_kh(@percent,b.funcPara) AS r 
FROM kh_main AS a
INNER JOIN kh_item AS b ON a.mainId=b.mainId AND @percent>b.beginPercent AND @percent<=b.endPercent 
WHERE [year]=2017
非常感谢,完美的解决了我的问题!
日月路明 2017-12-02
  • 打赏
  • 举报
回复
比较简单鲁莽的做法: 直接写一个函数,类似下面的结构,以后不断扩充年份就行了 create func GetScore( @Year int,---年份 @wcl money,--完成率 ) returns int as begin declare @sore int if @Year=2017 begin ...... end if @Year=2016 begin end return(@score) end
snakefish 2017-12-02
  • 打赏
  • 举报
回复
引用 1 楼 yenange 的回复:
USE tempdb
GO
IF OBJECT_ID('kh_main') IS NOT NULL DROP TABLE kh_main
GO
IF OBJECT_ID('kh_item') IS NOT NULL DROP TABLE kh_item
GO
--考核主要表,设置起始时间主要是为防止一年有多个考核标准
CREATE TABLE kh_main (
	mainId INT IDENTITY(1,1) PRIMARY KEY,
	[year] INT NOT NULL,			
	[beginTime] DATETIME NOT NULL,	
	endTime DATETIME NOT NULL
)
GO
CREATE TABLE kh_item(
	itemId INT IDENTITY(1,1),
	mainId INT NOT NULL,
	[case] VARCHAR(300) NOT NULL,
	changeScore INT NOT NULL
)

供参考吧
感谢版主回答,想问一下表kh_item中case字段如何存储设定的标准?这也是我没想明白的地方,因为还涉及到后期取出数据进行比较。
吉普赛的歌 版主 2017-12-02
  • 打赏
  • 举报
回复
/* funcPara r 3 110.00 */
吉普赛的歌 版主 2017-12-02
  • 打赏
  • 举报
回复
#3 的思路很好, 把我#2和他的思路结合一下:
USE tempdb
GO
IF OBJECT_ID('kh_main') IS NOT NULL DROP TABLE kh_main
GO
IF OBJECT_ID('kh_item') IS NOT NULL DROP TABLE kh_item
GO
--考核主要表,设置起始时间主要是为防止一年有多个考核标准
CREATE TABLE kh_main (
	mainId INT IDENTITY(1,1) PRIMARY KEY,
	[year] INT NOT NULL,			
	[beginTime] DATETIME NOT NULL,	
	endTime DATETIME NOT NULL
)
GO
CREATE TABLE kh_item(
	itemId INT IDENTITY(1,1),
	mainId INT NOT NULL,
	[case] VARCHAR(300) NOT NULL,
	beginPercent DECIMAL(10,2),
	endPercent DECIMAL(10,2),
	[funcPara] INT NOT NULL
)
INSERT INTO kh_main(
	[year],
	beginTime,
	endTime
)
VALUES
(
	2017,
	'2017-01-01',
	'2017-12-31 23:59:59'
)

--有2条记录我加了等于两个字(跟前后记录不同),业务上最好商定:标准可以随便变, 但起止包括或不包括端点要讲清楚而且前后必须一致!
--避免不必要的纷争, 当然, 这是小事,找领导商定下来就可以了。
INSERT INTO kh_item(mainId,	[case],beginPercent,endPercent,[funcPara]) VALUES(	1,'完成率小于(等于)90%时,扣20分',0,90,1)
INSERT INTO kh_item(mainId,	[case],beginPercent,endPercent,[funcPara]) VALUES(	1,'大于90%小于等于100%时,每减少1%扣1分',10,100,2)
INSERT INTO kh_item(mainId,	[case],beginPercent,endPercent,[funcPara]) VALUES(	1,'大于100%小于(等于)110%时,每增加1%奖1分',100,110,3)
INSERT INTO kh_item(mainId,	[case],beginPercent,endPercent,[funcPara]) VALUES(	1,'大于等于110%时,每增加1%奖2分',110,9999999,4)
GO
IF OBJECT_ID('Fun_Kh') IS NOT NULL DROP FUNCTION Fun_kh
GO
-- =============================================
-- Author:		yenange	
-- Create date: 2017-12-02
-- Description:	考核函数
-- =============================================
CREATE FUNCTION Fun_kh(
	@percent INT,
	@funPara INT
)
RETURNS DECIMAL(10,2)
AS
BEGIN
	DECLARE @r DECIMAL(10,2)
	IF @funPara=1
	BEGIN
		SET @r=@percent-20
	END
	ELSE IF @funPara=2
	BEGIN
		SET @r=@percent-(@percent-90)
	END
	ELSE IF @funPara=3
	BEGIN
		SET @r=@percent+(@percent-100)
	END
	ELSE IF @funPara=4
	BEGIN
		SET @r=@percent+(@percent-110)
	END
	RETURN @r
END
GO
--某个项目是 2017 年度内的, 完成率为 110%
DECLARE @year INT,@percent INT
SELECT @year=2017,@percent=105

SELECT b.funcPara,dbo.FUN_kh(@percent,b.funcPara) AS r 
FROM kh_main AS a
INNER JOIN kh_item AS b ON a.mainId=b.mainId AND @percent>b.beginPercent AND @percent<=b.endPercent 
WHERE [year]=2017
吉普赛的歌 版主 2017-12-01
  • 打赏
  • 举报
回复
USE tempdb
GO
IF OBJECT_ID('kh_main') IS NOT NULL DROP TABLE kh_main
GO
IF OBJECT_ID('kh_item') IS NOT NULL DROP TABLE kh_item
GO
--考核主要表,设置起始时间主要是为防止一年有多个考核标准
CREATE TABLE kh_main (
	mainId INT IDENTITY(1,1) PRIMARY KEY,
	[year] INT NOT NULL,			
	[beginTime] DATETIME NOT NULL,	
	endTime DATETIME NOT NULL
)
GO
CREATE TABLE kh_item(
	itemId INT IDENTITY(1,1),
	mainId INT NOT NULL,
	[case] VARCHAR(300) NOT NULL,
	changeScore INT NOT NULL
)

供参考吧

34,590

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧