存储过程最大模式匹配
Stored Procedure Maximum Pattern Match
这是我在 Oracle 中的存储过程:
CREATE OR REPLACE PROCEDURE execute_cproc ( callnum IN VARCHAR2
, RESULT OUT VARCHAR2)
AS
vara_val NUMBER;
varb_val NUMBER;
BEGIN
SELECT a_val, b_val
INTO vara_val, varb_val
FROM data_table
WHERE callnum LIKE numberpattern || '%';
END;
如果 CALLNUM
是 03354123 那么我得到 2 个结果:
03354123 like 033%
03354123 like 03354%
两者都是正确的,所以我得到了 2 个结果。
如何让程序只找到最长的匹配,即 03354123 like 03354%
?
Table :
Table 姓名:DATA_TABLE
列:
NumberPattern (varchar2) : 033, 03354
a_val ( integer ) : 1, 2
b_val ( integer ) : 1, 2
您建议的解决方案是否提供了答案?
如果您的数据包含:
03354121
03354122
03354123
这些都将匹配 03354%。那么哪个最好呢?
也许没有答案。
一个"fix"是将数据降序排列,取第一个结果
你能做到吗(抱歉,我没有可用于测试的 Oracle 数据库):
select a_val, b_val into vara_val, varb_val
from (
select
a_val, b_val, NumberPattern, row_number() as r
from
DATA_TABLE
where
CALLNUM LIKE NumberPattern || '%'
order by NumberPattern DESC)
where r = 1;
由于我无法测试,您可能需要调整语法。
您必须重组您的查询。如果您想获得最佳或最大模式,请执行以下操作:
select a_val, b_val
into vara_val, varb_val
from
(select NumberPattern ,
a_val,
b_val,
rank() over(order by length(NumberPattern) desc) ranking
from DATA_TABLE
where CALLNUM like NumberPattern || '%' )
where ranking = 1
这会将您的变量 vara_val 和 varb_val 分别设置为值 2、2。或者,如果您也想获得该模式,只需声明另一个将保存该值的变量,然后将您的查询编辑为:
select NumberPattern ,a_val, b_val
into yournew_variable,vara_val, varb_val
from
(select NumberPattern ,
a_val,
b_val,
rank() over(order by length(NumberPattern) desc) ranking
from DATA_TABLE
where CALLNUM like NumberPattern || '%' )
where ranking = 1
这里有一个简短的解释:我创建了一个子查询,它由 NumberPattern 、a_val、b_val 和 NumberPattern 根据其长度排列的等级组成。这只会对存在于您提供的 CALLNUM 参数上的模式进行排名。因此,例如,您获得模式 12345,1234,789 并将 123456789 传递给 CALLNUM 参数,它只会对模式 12345 和 1234 进行排名,因为您的 CALLNUM 以 12345 和 1234 开头,而不是以 789 开头。排名后,我选择了来自排名为 1
的子查询的 NumberPattern,a_val 和 b_val
这是我在 Oracle 中的存储过程:
CREATE OR REPLACE PROCEDURE execute_cproc ( callnum IN VARCHAR2
, RESULT OUT VARCHAR2)
AS
vara_val NUMBER;
varb_val NUMBER;
BEGIN
SELECT a_val, b_val
INTO vara_val, varb_val
FROM data_table
WHERE callnum LIKE numberpattern || '%';
END;
如果 CALLNUM
是 03354123 那么我得到 2 个结果:
03354123 like 033%
03354123 like 03354%
两者都是正确的,所以我得到了 2 个结果。
如何让程序只找到最长的匹配,即 03354123 like 03354%
?
Table :
Table 姓名:DATA_TABLE
列:
NumberPattern (varchar2) : 033, 03354
a_val ( integer ) : 1, 2
b_val ( integer ) : 1, 2
您建议的解决方案是否提供了答案?
如果您的数据包含:
03354121 03354122 03354123
这些都将匹配 03354%。那么哪个最好呢?
也许没有答案。
一个"fix"是将数据降序排列,取第一个结果
你能做到吗(抱歉,我没有可用于测试的 Oracle 数据库):
select a_val, b_val into vara_val, varb_val
from (
select
a_val, b_val, NumberPattern, row_number() as r
from
DATA_TABLE
where
CALLNUM LIKE NumberPattern || '%'
order by NumberPattern DESC)
where r = 1;
由于我无法测试,您可能需要调整语法。
您必须重组您的查询。如果您想获得最佳或最大模式,请执行以下操作:
select a_val, b_val
into vara_val, varb_val
from
(select NumberPattern ,
a_val,
b_val,
rank() over(order by length(NumberPattern) desc) ranking
from DATA_TABLE
where CALLNUM like NumberPattern || '%' )
where ranking = 1
这会将您的变量 vara_val 和 varb_val 分别设置为值 2、2。或者,如果您也想获得该模式,只需声明另一个将保存该值的变量,然后将您的查询编辑为:
select NumberPattern ,a_val, b_val
into yournew_variable,vara_val, varb_val
from
(select NumberPattern ,
a_val,
b_val,
rank() over(order by length(NumberPattern) desc) ranking
from DATA_TABLE
where CALLNUM like NumberPattern || '%' )
where ranking = 1
这里有一个简短的解释:我创建了一个子查询,它由 NumberPattern 、a_val、b_val 和 NumberPattern 根据其长度排列的等级组成。这只会对存在于您提供的 CALLNUM 参数上的模式进行排名。因此,例如,您获得模式 12345,1234,789 并将 123456789 传递给 CALLNUM 参数,它只会对模式 12345 和 1234 进行排名,因为您的 CALLNUM 以 12345 和 1234 开头,而不是以 789 开头。排名后,我选择了来自排名为 1
的子查询的 NumberPattern,a_val 和 b_val