SQL解析值列表以查找大于/小于/范围
Posted
技术标签:
【中文标题】SQL解析值列表以查找大于/小于/范围【英文标题】:SQL parse list of values to find greater than/ less than/ range 【发布时间】: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。然而,更好的选择是正确规范您的数据模型 【参考方案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;
【讨论】:
以上是关于SQL解析值列表以查找大于/小于/范围的主要内容,如果未能解决你的问题,请参考以下文章