簡體   English   中英

ORACLE-選擇對子查詢計數

[英]ORACLE - Select Count on a Subquery

我有一個Oracle表,其中包含一組范圍(RangeA和RangeB)。 這些列是varchar,因為它們可以同時包含數字和字母數字值,例如以下示例:

ID|RangeA|RangeB
1 |   10 |   20
2 |   21 |   30
3 | AB50 | AB70
4 | AB80 | AB90

我需要執行一個查詢,該查詢僅返回具有數字值的記錄,並對該查詢執行Count。 到目前為止,我已經嘗試通過兩個不同的查詢來做到這一點,但沒有任何運氣:

查詢1:

SELECT COUNT(*) FROM (
SELECT RangeA, RangeB FROM table R
WHERE upper(R.RangeA) = lower(R.RangeA)
) A
WHERE TO_NUMBER(A.RangeA) <= 10

查詢2:

WITH A(RangeA,RangeB) AS(
SELECT RangeA, RangeB FROM table 
WHERE upper(RangeA) = lower(RangeA)
)
SELECT COUNT(*) FROM A WHERE TO_NUMBER(A.RangeA) <= 10

子查詢工作正常,因為我得到的兩個記錄只有數字值,但查詢的COUNT部分失敗。 我應該只得到1,但是我得到了以下錯誤:

ORA-01722: invalid number
01722. 00000 -  "invalid number"

我究竟做錯了什么? 任何幫助深表感謝。

試試這個查詢:

  SELECT COUNT(*)
  FROM table R
  WHERE translate(R.RangeA, 'x0123456789', 'x') = 'x' and
        translate(R.RangeB, 'x0123456789', 'x') = 'x'

首先,您不需要為此使用子查詢。 其次,使用to_number()upper() / lower()容易出現其他問題。 函數translate()將第二個參數中的每個字符替換為第三個參數中的值。 在這種情況下,它將刪除數字。 如果沒有剩余,則原始值為整數。

您可以對負值和浮點數進行更復雜的檢查,但是問題中的示例似乎與正整數有關。

您可以使用正則表達式測試每一列,以確定其是否為有效數字:

SELECT COUNT(1)
FROM   table_of_ranges
WHERE  CASE WHEN REGEXP_LIKE( RangeA, '^-?\d+(\.\d*)?$' )
            THEN TO_NUMBER( RangeA )
            ELSE NULL END
          < 10
AND    REGEXP_LIKE( RangeB, '^-?\d+(\.\d*)?$' );

另一種選擇是使用用戶定義的函數:

CREATE OR REPLACE FUNCTION test_Number (
  str VARCHAR2
) RETURN NUMBER DETERMINISTIC
AS
  invalid_number EXCEPTION;
  PRAGMA EXCEPTION_INIT(invalid_number, -6502);
BEGIN
  RETURN TO_NUMBER( str );
EXCEPTION
  WHEN invalid_number THEN
    RETURN NULL;
END test_Number;
/

然后,您可以執行以下操作:

SELECT COUNT(*)
FROM   table_of_ranges
WHERE  test_number( RangeA ) <= 10
AND    test_number( RangeB ) IS NOT NULL;

差不多四年后才出現這個問題(很明顯,這里是從更新的話題中指出的)。 其他答案顯示了如何實現所需的輸出,但沒有回答OP的問題,即“ 我做錯了什么?

您沒有做錯任何事。 Oracle做錯了。 它是將謂詞( WHERE條件)從外部查詢“推入”內部查詢。 推謂詞是Optimizer使查詢更高效的最基本方法之一,但是在某些情況下(並且您所問的問題是PERFECT的例證),其結果在邏輯上實際上並不等同於原始查詢。

有多種方法可以防止Optimizer推入謂詞。 或者您可以以更好的方式編寫查詢(如其他答案所示)。 但是,如果您想知道為什么看到自己看到的東西,這就是原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM