SQL查询将与多个范围匹配的数字列表转换为值列表
Posted
技术标签:
【中文标题】SQL查询将与多个范围匹配的数字列表转换为值列表【英文标题】:SQL query to translate a list of numbers matched against several ranges, to a list of values 【发布时间】:2010-04-14 08:35:21 【问题描述】:我需要将某个范围内的数字列表转换为按优先级列排序的值列表。该表具有以下值:
| YEAR | R_MIN | R_MAX | VAL | PRIO |
------------------------------------
2010 18000 90100 52 6
2010 240000 240099 82 3
2010 250000 259999 50 5
2010 260000 260010 92 1
2010 330000 330010 73 4
2010 330011 370020 50 5
2010 380000 380050 84 2
不同年份的范围会有所不同。一年内的范围永远不会重叠。
输入将是年份和可能在这些范围内的数字列表。输入数字的列表将很小,1 到 10 个数字。输入数字示例:
(20000, 240004, 375000, 255000)
通过该输入,我想获得一个按优先级列排序的列表,或单个值:
82
50
52
我在这里感兴趣的唯一值是 82,所以 UNIQUE 和 MAX_RESULTS=1 就可以了。可以很容易地对每个数字进行一次查询,然后在 Java 代码中对其进行排序,但我更愿意在单个 SQL 查询中进行。
在 Oracle 数据库中运行什么 SQL 查询会给我想要的结果?
(注意,这不是关于splitting an input string,而是关于将值列表中的每个值与不同列中定义的范围进行匹配。)
【问题讨论】:
Is there a function to split a string in PL/SQL?的可能重复 【参考方案1】:我猜你想将这组数字作为字符串传递并拆分为单独的数字。这比您想象的要难,因为 Oracle 没有内置标记器。很奇怪吧?
有许多 PL/SQL 标记器解决方案围绕着 Das Interwabs。我正在使用Anup Pani's implementation 的变体,它使用正则表达式(因此只有Oracle 10g 或更高版本)。我的变体返回一个我已声明为 SQL 类型的数字数组:
SQL> create or replace type numbers as table of number
2 /
Type created.
SQL>
这意味着我可以在 SELECT 语句中将它用作 TABLE() 函数的输入:
SQL> select * from table (str_to_number_tokens('20000, 240004, 375000, 255000'))
2 /
COLUMN_VALUE
------------
20000
240004
375000
255000
SQL>
这意味着我可以将你的数字字符串转换成一个表格,我可以在查询中加入该表格,如下所示:
SQL> select val
2 from t23
3 , ( select column_value as i_no
4 from table (str_to_number_tokens('20000, 240004, 375000, 255000')) ) sq
5 where t23.year = 2010
6 and sq.i_no between t23.r_min and t23.r_max
7 order by t23.priority
8 /
VAL
----------
82
50
52
SQL>
【讨论】:
谢谢!这确实比我最初想象的要复杂得多。 @ClaesMogren - 这是第一次有点傻的事情,因为我们必须建立一些基础设施。但在那之后就很容易了。【参考方案2】:我认为您的第一个任务是将数字列表转换为您可以加入的结果集(即内存表)。我不了解 Oracle,因此可能有一种简单的方法可以做到这一点,但如果没有,您将需要编写某种用户定义的函数来执行此操作。它不应该太难,性能也不是问题,因为列表很小。然后,您可以连接到该表。像这样的:
SELECT yt.val
FROM your_table yt
JOIN your_parse_numbers_function(@inputlist) il
ON il.value >= yt.R_MIN AND il.value <= yt.R_MAX
WHERE yt.YEAR = @year
如果您愿意,您可以将其限制为 1 个结果,但如果您关于范围不重叠的假设是正确的,那么它应该只返回 1。
【讨论】:
嗯...这会起作用,但我不确定如何制作结果集。我去看看。以上是关于SQL查询将与多个范围匹配的数字列表转换为值列表的主要内容,如果未能解决你的问题,请参考以下文章