回答

收藏

ORACLE-选择对子查询计数

技术问答 技术问答 112 人阅读 | 0 人回复 | 2023-09-13

我有一个Oracle表,其中包含一组范围(RangeA和RangeB)。这些列是varchar,因为它们可以同时容纳数字和字母数字值,如以下示例所示:4 h4 ^/ g8 Z) r! x
ID|RangeA|RangeB
% l- ~4 {7 {% `1 |   10 |   20
2 A. O( d0 K$ t2 |   21 |   30: |9 @4 \5 Y' }# _% f: L7 P1 R
3 | AB50 | AB70
" V* P/ Z' Q- ^+ w1 C1 {8 c! _4 | AB80 | AB90
) ~2 A  {# D! Y. x1 I2 Z我需要执行一个查询,该查询仅返回具有数值的记录,并对该查询执行Count。到目前为止,我已经尝试过使用两个不同的查询来做到这一点,但没有任何运气:3 y7 @0 E" |6 U# U
查询1:  
# n3 s9 C! {! w$ PSELECT COUNT(*) FROM (
" j2 u# m7 W! ]- T) MSELECT RangeA, RangeB FROM table R
8 R! k8 g) K7 l: z% @WHERE upper(R.RangeA) = lower(R.RangeA)
( }. ]; I$ T: h0 u7 t% c) A
0 D% S+ E. n5 X3 t3 NWHERE TO_NUMBER(A.RangeA) 查询2:5 R0 ^; U% H; \; t6 I
WITH A(RangeA,RangeB) AS(
  Y8 Z9 S/ w5 s# ISELECT RangeA, RangeB FROM table 6 p4 E! z; @; W7 |# H9 d
WHERE upper(RangeA) = lower(RangeA)
/ e* }4 g% ~% o: h4 ~9 p8 C. @)2 b8 z7 l  X, d$ I8 h
SELECT COUNT(*) FROM A WHERE TO_NUMBER(A.RangeA) 子查询工作正常,因为我得到的两个记录都只有数字值,但是查询的COUNT部分失败了。我应该只得到1,但是我得到了以下错误:
4 k, C# B' R9 n' k& RORA-01722: invalid number1 ~$ }8 J& E' y1 f( E
01722. 00000 -  "invalid number"4 _3 \: W, X" j
我究竟做错了什么?任何帮助深表感谢。6 r" _$ O( z' Q
               
; K4 s' H# M7 L# _解决方案:1 c% N5 t7 k# B* q+ w
                # p2 p& S3 }1 k+ d; f8 T

6 m  E: d# i0 h) l% X" q# |8 h! I6 j
+ [2 ^8 X; Q& o- a                您可以使用正则表达式测试每一列,以确定其是否为有效数字:2 t, D7 S% N' O4 p" T4 M
SELECT COUNT(1)
2 j' u! d! d1 S  \% r) XFROM   table_of_ranges
9 y' z; x- y, z" S: |; I" wWHERE  CASE WHEN REGEXP_LIKE( RangeA, '^-?\d+(\.\d*)?$' )$ M: j+ Z3 Z: R
            THEN TO_NUMBER( RangeA )
) s5 T( [: b3 J, X4 D            ELSE NULL END# s& R( C* n" F6 k
          另一种选择是使用用户定义的函数:
) p3 c6 V! O7 P+ y( K) [+ B6 TCREATE OR REPLACE FUNCTION test_Number (7 e. ]3 f& _# D
  str VARCHAR26 Y, ~4 M3 k% z9 {, x$ k
) RETURN NUMBER DETERMINISTIC* d# d+ q7 [* l5 M$ Q
AS, E2 I: s# F$ C. P6 ]9 f1 c
  invalid_number EXCEPTION;
# ^: W  F; p7 v+ `. L  PRAGMA EXCEPTION_INIT(invalid_number, -6502);3 Q0 }+ ?. T( B( r8 B, l
BEGIN  y" m$ |4 e! Z( m3 F
  RETURN TO_NUMBER( str );* g' y) u2 x$ B+ h2 b- G1 M/ P1 ?
EXCEPTION
4 M2 ^2 y- y( T8 c, C& R' A" M  WHEN invalid_number THEN9 }$ `8 u6 m' F- e9 w
    RETURN NULL;' g! b. N" y  _" ^) w
END test_Number;
) ^9 |, {) ?! C; V* s  M1 x/
4 O, p! k4 F3 _! B% A/ J) }然后,您可以执行以下操作:
% _( H/ d# W' U# V5 sSELECT COUNT(*)
  i$ ]4 s  c% V1 \FROM   table_of_ranges+ z5 u' N+ ^+ x; [3 f. X' Q
WHERE  test_number( RangeA ) <= 105 z+ a6 Z1 B$ P1 f# Y/ L
AND    test_number( RangeB ) IS NOT NULL;
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则