2017-12-31 307 views
2

データベースで年齢を計算するためのUDFを作成しました。年齢ブラケットを計算するSQL Serverユーザー定義関数

SELECT [dbo].[Agebracket](10) 

出力[として出てきた:私は、以下の例でテストする場合、次のコードを

CREATE FUNCTION Agebracket(@Ages INT) 
RETURNS VARCHAR 
AS 
BEGIN 
DECLARE @Age_Group varchar 

SET @Age_Group = CASE WHEN @Ages BETWEEN 0 AND 9 THEN '[0-9]' 
       WHEN @Ages BETWEEN 10 AND 19 THEN '[10-19]' 
       WHEN @Ages BETWEEN 20 AND 29 THEN '[20-29]' 
       WHEN @Ages BETWEEN 30 AND 39 THEN '[30-39]' 
       WHEN @Ages BETWEEN 40 AND 49 THEN '[40-49]' 
       WHEN @Ages BETWEEN 50 AND 59 THEN '[50-59]' 
       WHEN @Ages BETWEEN 60 AND 69 THEN '[60-69]' 
       WHEN @Ages BETWEEN 70 AND 79 THEN '[70-79]' 
       WHEN @Ages BETWEEN 80 AND 89 THEN '[80-89]' 
       WHEN @Ages BETWEEN 90 AND 99 THEN '[90-99]' 
       WHEN @Ages>=100 THEN '[100+]' end 
RETURN @Age_Group 
END 

を用います。

私は出力が[10-19]

答えて

3

DECLARE @Age_Group varchar(8)DECLARE @Age_Group varcharを交換しても、あなたの関数がvarchar(8)を返すために作ることを期待して、私は何ができるか上の任意のアイデア。バージョンの作業

:SQL Serverは、(1)VARCHAR = VARCHARを想定し、さらに悪化するので

alter FUNCTION Agebracket(@Ages INT) 
RETURNS VARCHAR(8) 
AS 
BEGIN 
DECLARE @Age_Group varchar(8) 

SET @Age_Group = CASE WHEN @Ages BETWEEN 0 AND 9 THEN '[0-9]' 
       WHEN @Ages BETWEEN 10 AND 19 THEN '[10-19]' 
       WHEN @Ages BETWEEN 20 AND 29 THEN '[20-29]' 
       WHEN @Ages BETWEEN 30 AND 39 THEN '[30-39]' 
       WHEN @Ages BETWEEN 40 AND 49 THEN '[40-49]' 
       WHEN @Ages BETWEEN 50 AND 59 THEN '[50-59]' 
       WHEN @Ages BETWEEN 60 AND 69 THEN '[60-69]' 
       WHEN @Ages BETWEEN 70 AND 79 THEN '[70-79]' 
       WHEN @Ages BETWEEN 80 AND 89 THEN '[80-89]' 
       WHEN @Ages BETWEEN 90 AND 99 THEN '[90-99]' 
       WHEN @Ages>=100 THEN '[100+]' end 
RETURN @Age_Group 
END 
GO 

SELECT [dbo].[Agebracket](10) 

これは、それは静かに値が切り捨てられますされています。

5

パフォーマンスが重要な場合、スカラー関数はあなたのためではありません。インラインテーブル値関数(itvf)は、ほとんどの場合常に優れたパフォーマンスを示します。 Alexeiがitvfに投稿したものを回すことで、機能が6倍速くなります私のPC上で。私に実証させてください。まず、CHOOSEを使用するソリューションを次に示します。私はCHOOSEが好きです。なぜなら、クリーナーだからです(しかし、古い学校のCASEステートメントよりも速くはありません)。

CREATE FUNCTION dbo.agebracket(@Ages tinyint) 
RETURNS VARCHAR(10) AS 
BEGIN RETURN '['+(isnull(choose(@ages/10+1,'0-9','10-19','20-29','30-39', 
      '40-49','50-59','60-69','70-79','80-89','90-99'),'100+'))+']' END 

我々は負の数をしたくないので、私はtinyint型を使用して(あなたが国、恐竜の骨などの話をしている場合を除き)256は、年齢を処理するために十分であることに注意してください...

今みましょうこれをインラインテーブル値関数として書き直してください。

CREATE FUNCTION dbo.agebracket_itvf(@Ages tinyint) 
RETURNS TABLE AS RETURN 
SELECT ages = 
'['+(isnull(choose(@ages/10+1,'0-9','10-19','20-29','30-39', 
      '40-49','50-59','60-69','70-79','80-89','90-99'),'100+'))+']'; 

次は、パフォーマンステストのサンプルデータです。

if object_id('tempdb..#ageList') is not null drop table #ageList; 
GO 
create table #ageList (age tinyint); 
insert #ageList 
select top (1000000) abs(checksum(newid())%100)+1 
from sys.all_columns a, sys.all_columns b; 

我々はテストする前に、ここでは、各機能を使用する方法は次のとおりです。

-- scalar version 
select top(10) t.age, ages = dbo.agebracket(t.age) 
from #ageList t; 

-- itvf version 
select top(10) t.age, fn.ages 
from #ageList t 
cross apply dbo.agebracket_itvf(t.age) fn; 

結果:今

age ages 
---- ---------- 
76 [70-79] 
19 [10-19] 
32 [30-39] 
58 [50-59] 
40 [40-49] 
22 [20-29] 
41 [40-49] 
66 [60-69] 
74 [70-79] 
31 [30-39]  

age ages 
---- ------- 
76 [70-79] 
19 [10-19] 
32 [30-39] 
58 [50-59] 
40 [40-49] 
22 [20-29] 
41 [40-49] 
66 [60-69] 
74 [70-79] 
31 [30-39] 

性能試験。

print 'scalar version'+char(13)+char(10)+replicate('-',50); 
go 
declare @st datetime = getdate(), @x varchar(10); 
select @x = dbo.agebracket(t.age) 
from #ageList t 
print datediff(ms,@st,getdate()); 
GO 3 

print 'itvf version'+char(13)+char(10)+replicate('-',50); 
go 
declare @st datetime = getdate(), @x varchar(10); 
select @x = fn.ages 
from #ageList t 
cross apply dbo.agebracket_itvf(t.age) fn 
print datediff(ms,@st,getdate()); 
GO 3 

結果は次のとおりです。 もう一度、itvfバージョンは6倍高速でした!

scalar version 
-------------------------------------------------- 
Beginning execution loop 
2140 
2167 
2267 
Batch execution completed 3 times. 

itvf version 
-------------------------------------------------- 
Beginning execution loop 
380 
383 
370 
Batch execution completed 3 times. 
関連する問題