01.
if object_id ( N
'dbo.test_table'
, N
'U'
)
is
not
null
02.
drop
table
dbo.test_table;
03.
go
04.
05.
create
dbo.test_table ( id
int
identity
06.
, a
07.
, b
08.
, c
09.
, d
10.
, e
11.
);
12.
13.
14.
insert
into
dbo.test_table
15.
select
10, 5, 12, 56, 2
16.
union
all
17.
100, 45, 78, 6, 122
18.
19.
150, 50, 127, 596, 22
20.
21.
3410, 55, 0, -45, 90
22.
23.
-10, -5, 0, -56, -2;
24.
*
, max_val =
case
when
( a >= b )
and
( a >= c )
( a >= d )
( a >= e )
then
a
( b >= a )
( b >= c )
( b >= d )
( b >= e )
b
( c >= a )
( c >= b )
( c >= d )
( c >= e )
c
( d >= a )
( d >= b )
( d >= c )
( d >= e )
d
else
e
end
from
, max_val = (
max
(i)
(
) t(i)
values
(a)
,(b)
,(c)
,(d)
,(e)
1.
id,
(val)
as
max_val
2.
3.
dbo.test_table t
4.
unpivot ( val
for
col
in
( [a],[b],[c],[d],[e]) ) up
5.
6.
) t
7.
group
by
id
top
1
with
ties id, val
order
row_number() over ( partition
val
desc
cross
apply (
1 val
(a),(b),(c),(d),(e) ) t (val)
) ca (max_val)
--Ещё вариант
id, a, b, c, d, e, max_val
row_number() over (
) i, val
) ca (i, max_val)
where
ca.i = 1
'dbo.f_get_max'
'IF'
function
dbo.f_get_max;
dbo.f_get_max (
@a
, @b
, @c
, @d
, @e
returns
return
cte
(@a),(@b),(@c),(@d),(@e)
) t(val)
cte;
apply dbo.f_get_max ( a, b, c, d, e )
001.
set
nocount
on
;
002.
003.
004.
005.
006.
007.
008.
primary
key
clustered
009.
010.
011.
012.
013.
014.
015.
016.
017.
--Генерим 10 млн строк
018.
019.
020.
021.
1 i
022.
023.
i+1
i < 10000000
024.
025.
026.
checksum ( newid() ) % 1000
027.
, checksum ( newid() ) % 1000
028.
029.
030.
031.
032.
option
( maxrecursion 0 );
033.
034.
declare
@val
035.
036.
print
'1. Выражение CASE (любая версия)'
037.
statistics
time
038.
039.
@val =
040.
041.
042.
043.
044.
045.
046.
047.
048.
049.
050.
051.
off
052.
053.
'2. Подзапрос и оператор UNION (любая версия)'
054.
055.
056.
@val = (
057.
058.
059.
060.
061.
062.
063.
064.
065.
066.
067.
068.
069.
070.
071.
072.
'3. Подзапрос и предложение VALUES (SQL Server 2008 и выше)'
073.
074.
075.
076.
077.
078.
079.
080.
081.
082.
083.
084.
085.
086.
087.
'4. Оператор UNPIVOT (SQL Server 2005 и выше)'
088.
089.
090.
091.
092.
093.
094.
095.
096.
id;
097.
098.
099.
100.
'5. Оператор UNPIVOT и ранжирующие функции (SQL Server 2005 и выше)'
101.
102.
103.
ties @val = val
104.
105.
106.
107.
108.
109.
110.
'6. Оператор CROSS APPLY (SQL Server 2005 и выше)'
111.
112.
'CROSS APPLY 1'
113.
114.
@val = max_val
115.
116.
117.
118.
119.
) ca (max_val);
120.
121.
'CROSS APPLY 2'
122.
123.
124.
125.
126.
127.
ca.i = 1;
128.
129.
130.
131.
'7. Inline-функция и CTE (SQL Server 2005 и выше)'
132.
133.
134.
135.
apply dbo.f_get_max ( a, b, c, d, e );
136.
137.
138.
1. Выражение
CASE
(любая версия)
SQL Server Execution Times:
CPU
= 3416 ms, elapsed
= 3416 ms.
----------------------------------------------------------------------
2. Подзапрос и оператор
UNION
= 12777 ms, elapsed
= 3848 ms.
3. Подзапрос и предложение
VALUES
(SQL Server 2008 и выше)
= 13182 ms, elapsed
= 3968 ms.
4. Оператор UNPIVOT (SQL Server 2005 и выше)
= 22246 ms, elapsed
= 15966 ms.
25.
5. Оператор UNPIVOT и ранжирующие функции (SQL Server 2005 и выше)
26.
27.
28.
= 153957 ms, elapsed
= 239071 ms.
29.
30.
31.
6. Оператор
CROSS
APPLY (SQL Server 2005 и выше)
32.
33.
APPLY 1
34.
35.
36.
= 22963 ms, elapsed
= 6273 ms.
37.
38.
APPLY 2
39.
40.
41.
= 33244 ms, elapsed
= 9270 ms.
42.
43.
44.
7. Inline-функция и CTE (SQL Server 2005 и выше)
45.
46.
47.
= 12246 ms, elapsed
= 3787 ms.