【问题标题】:SQL parse list of values to find greater than/ less than/ rangeSQL解析值列表以查找大于/小于/范围
【发布时间】:2018-01-26 12:25:15
【问题描述】:

我有一个 Oracle SQL DB 列,其中包含一个逗号分隔的值列表,作为输入,我有两个数字 - 我需要确定值列表中的至少一个数字是否介于两个输入数字之间。

示例:
DB栏目内容:'100, 200, 300, 400, 500'
输入:10、100
请求的输出:true(因为 100 介于 10 和 110 之间)。

输入:10,80。
请求的输出:false。

有什么方法可以直接使用 SQL(没有 PL/SQL)吗?

【问题讨论】:

  • 由于 Oracle 没有内置支持来处理逗号分隔值,我想您将不得不为此使用 PL/SQL。然而,更好的选择是正确规范您的数据模型

标签: sql oracle


【解决方案1】:

您可以使用XMLTABLE

SQL Fiddle

Oracle 11g R2 架构设置

create table yourtable as select '100, 200, 300, 400, 500' nums from dual;

查询 1

 WITH t(n)
     AS (SELECT TO_NUMBER (column_value)
         FROM   yourtable,
                XMLTABLE(nums)),
     input(min_val, max_val)
     AS (SELECT Min(TO_NUMBER(column_value)),
                Max(TO_NUMBER(column_value))
         FROM   XMLTABLE('10,100' ))
SELECT CASE
         WHEN EXISTS (SELECT 1
                      FROM   t
                      WHERE  t.n BETWEEN i.min_val AND i.max_val) THEN 'TRUE'
         ELSE 'FALSE'
       END is_between
FROM   input i

Results

| IS_BETWEEN |
|------------|
|     TRUE   |

【讨论】:

    【解决方案2】:

    你可以像这样创建一个函数:

    CREATE OR REPLACE TYPE NUMBER_TABLE_TYPE AS TABLE OF NUMBER;
    
    CREATE OR REPLACE FUNCTION SplitCSV(LIST IN VARCHAR2, Separator IN VARCHAR2) RETURN NUMBER_TABLE_TYPE IS
        OutTable NUMBER_TABLE_TYPE := NUMBER_TABLE_TYPE();  
    BEGIN
        SELECT REGEXP_SUBSTR(LIST, '[^'||Separator||']+', 1, LEVEL) 
        BULK COLLECT INTO OutTable
        FROM dual
        CONNECT BY REGEXP_SUBSTR(LIST, '[^'||Separator||']+', 1, LEVEL) IS NOT NULL;
    
        RETURN OutTable;
    END;
    

    然后你可以使用它,例如:

    WITH t AS (SELECT '100, 200, 300, 400, 500' AS val FROM dual)
    SELECT distinct 'true'
    FROM t
        CROSS JOIN TABLE(SplitCSV(val, ','))
    WHERE COLUMN_VALUE BETWEEN 10 and 80;
    

    或者在一个 SELECT 中完成所有操作:

    WITH t AS 
        (SELECT TO_NUMBER(REGEXP_SUBSTR('100, 200, 300, 400, 500', '[^,]+', 1, LEVEL)) AS NUMBERS
        FROM dual
        CONNECT BY REGEXP_SUBSTR('100, 200, 300, 400, 500', '[^,]+', 1, LEVEL) IS NOT NULL)
    SELECT case when count(NUMBERS) > 0 then 'TRUE' else 'FALSE' end 
    FROM t
    WHERE NUMBERS BETWEEN 10 AND 80;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-11
      • 1970-01-01
      • 1970-01-01
      • 2022-01-13
      相关资源
      最近更新 更多