|
大多数数据库都有类似GREATEST函数的功能,有时可能会有用。至少这些数据库没有这样的功能:
& w/ `" {5 J! Z; |% h. @Derby
6 X! N/ W! q1 f# w/ pSQL Server
9 \5 e" ^! E" FSybase ASE
% c2 ?% P0 H1 b! O I9 TSybase SQL Anywhere- Y- N& p( K; X+ W6 J3 L
' n9 @4 R% b( {# n% G! b; x
对于SQL Server和Sybase SQL Anywhere,可以使用子查询对函数进行仿真UNION) m. ~- V( U4 t0 w3 Q
ALL,并且可以在此问题中看到。一个例子:
% {# M! r8 o1 R' _- k# {+ ?-- SELECT GREATEST(field1, field2, field3) FROM my_table* O( o9 J/ S4 x3 k
SELECT (SELECT MAX(c) FROM
. }5 W0 g+ e, P0 e1 i, V (SELECT my_table.field1 AS c UNION ALL " E# ^6 h: K( o7 Y
SELECT my_table.field2 UNION ALL
1 d7 Y" a8 b" G5 U0 f4 H SELECT my_table.field3) T) AS greatest8 V" a% G/ @0 h6 O2 m/ B, @
FROM my_table _* @# P9 I. m% P- r' ?; n* X
但这在Sybase ASE中不起作用。显然,子查询无权访问外部查询的my_table引用。我得到的错误是' H" C7 O$ e4 F# Y1 A4 d9 G- ~
+ O* E2 O2 N3 h2 {8 x( i$ g% J
列前缀“ my_table”与查询中使用的表名或别名不匹配。该表要么未在FROM子句中指定,要么具有必须使用的相关名称+ C2 p8 k& O0 n/ C" V6 H
8 Q) z( B, J# ^& ^" L8 K
注意,Sybase SQL Anywhere不会出现此问题。知道这里出了什么问题以及如何重新编写查询吗?
) f2 U v* ?- L% U2 z$ }# q" ` u我想避免
' b: t4 v5 H- ^ z& [7 V5 b存储的函数,因为我可能没有创建它们的必要授权5 H3 f. t+ R( o
冗长CASE的表达式,与嵌套所需的所有比较的组合排列的表达长度CASE表达式至少O(n^2)当n是参数数GREATEST
9 \ @& [+ {( \2 t/ a9 r7 ?0 t
$ \1 K/ G) z6 i" w
6 T' Y& U' O9 o8 M) E) N& @# c- r0 `解决方案:7 ^9 C# x9 h' |2 }; V
+ L0 Z1 ]6 F! o% }, ]7 i5 s& w( {7 F5 \; Z0 \
, C5 t5 T/ g) U3 g# x
据我了解,逻辑(忽略空值)是: l) t1 ?- d7 ]+ t5 `* l
SELECT CASE $ Z8 J$ T; [1 e# [" Y+ x& N
WHEN field1 >= field2 3 g) N% Z) e/ {& a2 U$ |' q
AND field1 >= field3
+ ~8 M5 ]( r; N: W9 `' W! v8 i' l THEN field1
# A1 k; E1 t& z( Z; J {) ~( m WHEN field2 >= field3
+ n+ h. I/ ]: A THEN field2
( {2 l3 R/ X' G3 M( J' _( E ELSE field3& F) P {6 }7 Y
END AS greatest
! Q& x+ d# n2 f" i* p( k$ ~% r- X FROM my_table;( c1 j4 j4 f% j: T( g+ }
…但仅当所有值均为null时,才应返回null。
2 ?2 K' O4 S9 ?2 i: Y
: ^& F3 i/ j2 N我认为这是我更希望能够做的事情(尽管Sybase ASE不支持公用表表达式):
8 o: K* P9 v7 n6 ?WITH my_table$ ?! G0 F$ o# l
AS , k! Y8 j% W; O6 A$ `6 \. z
(
5 T7 J, J2 C) Q/ ^. C SELECT *
( Q i5 O( s. x) C$ z: v: u- Q FROM () {' d; Y/ n1 d: J0 i" C
VALUES ('A', 1, 2, 3), . G) ^9 l h7 G/ `
('B', 2, 3, 1), & }' k' }5 \1 ^" T1 _- q
('C', 3, 1, 2),2 A4 G% y3 b; [( M) t
('D', NULL, 2, 3),
X; ?- ^: H' l9 C+ l, R* Z ('E', NULL, NULL, 3), 8 i5 z, `! P9 x j+ s
('F', NULL, 3, NULL),
& r+ o: e! H) W ('G', 1, NULL, 3),
; m3 u* i6 Q0 N9 L+ d ('H', 1, 3, NULL),
$ Z( Q% M1 r/ s/ ]1 k1 R ('X', NULL, NULL, NULL)
# X! x" E! [0 X$ X ) AS T (ID, field1, field2, field3)
8 V6 w$ e, k& `- ?, G1 S. S ), * r' i/ m% @, _2 @ w% O
T1
6 }( R( j0 }# \ AS
2 }- ?, T ?2 O! \ (" M4 s" J/ q: _( ~" g
SELECT ID, field1 AS field_n
; x2 d; Y _( |+ k$ K$ P FROM my_table
: ^1 B" o% \6 P8 V5 F1 b2 M UNION
, T0 M/ f; z/ @9 _: ^; T SELECT ID, field2 AS field_n
# R8 K8 {/ T8 r- {1 f0 p FROM my_table$ s. A/ v' Z+ x2 T& m
UNION
3 m8 d: N8 F) x8 @& y SELECT ID, field3 AS field_n- l1 @0 _! ~% E* L+ `
FROM my_table
8 V) {, R6 b* {4 q& c8 n )
" n4 w1 ^' R8 `" Y5 \. xSELECT ID, MAX(field_n) AS greatest
% R$ p" x& y* ]) `+ Y7 t6 O FROM T1
3 F' [6 r% ~* {5 n, n; B GROUP
7 f! c- U2 y4 f3 S5 F, K$ F BY ID; |
|