Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle 11g:需要获取以另一个字符串开头的最长匹配字符串_Oracle_Oracle11g - Fatal编程技术网

Oracle 11g:需要获取以另一个字符串开头的最长匹配字符串

Oracle 11g:需要获取以另一个字符串开头的最长匹配字符串,oracle,oracle11g,Oracle,Oracle11g,我有两个数据表: CREATE TABLE tbl1 ( ID NUMBER, LABEL VARCHAR2(50) ); CREATE TABLE tbl2 ( ID NUMBER, SRC VARCHAR2(400) ); INSERT INTO tbl1 VALUES (1, 'foobar'); INSERT INTO tbl1 VALUES (2, 'foo'); INSERT INTO tbl1 VALUES (3, 'bar'); INSERT INTO tbl

我有两个数据表:

CREATE TABLE tbl1 (
  ID NUMBER,
  LABEL VARCHAR2(50)
);
CREATE TABLE tbl2 (
  ID NUMBER,
  SRC VARCHAR2(400)
);

INSERT INTO tbl1 VALUES (1, 'foobar');
INSERT INTO tbl1 VALUES (2, 'foo');
INSERT INTO tbl1 VALUES (3, 'bar');

INSERT INTO tbl2 (SRC) VALUES ('foo: yeah');
INSERT INTO tbl2 (SRC) VALUES ('foobar: nope');
我试图通过匹配tbl1中最长的匹配字符串来更新tbl2的ID字段。我的意图是“foo:yeah”条目应获得ID 2,“foobar:nope”条目应获得ID 1:

UPDATE tbl2 t2
SET t2.ID = (SELECT t1.ID
             FROM tbl1 t1
             WHERE t2.SRC LIKE t1.LABEL || '%');
这样做会导致错误:“单行子查询返回多行”。这对我来说很有意义,所以我尝试了这个:

UPDATE tbl2 t2
SET t2.ID = (SELECT t1.ID
             FROM tbl1 t1
             WHERE t2.SRC LIKE t1.LABEL || '%'
             AND ROWNUM=1
             ORDER BY LENGTH(t1.LABEL) DESC);
但现在我得到了这个错误:“缺少右括号”。 在这种情况下,我不理解这个错误,括号格式正确。

缺少右括号是因为子查询中的
order by
子句;在那里是无效的

您还可以获得与订购相同级别的
ROWNUM
。那不会像你期望的那样。排序发生在最后,所以实际上您将得到一行-任何一行,哪一行是不确定的-然后您将按长度排序这一行,这不起任何作用

您需要另一级别的子查询来获取感兴趣的行:

UPDATE tbl2 t2
SET t2.ID = (
  SELECT ID FROM (
    SELECT t1.ID
    FROM tbl1 t1
    WHERE t2.SRC LIKE t1.LABEL || '%'
    ORDER BY LENGTH(t1.LABEL) DESC
  )
  WHERE ROWNUM=1
);
。。。但不幸的是,这也不起作用,并将得到另一个错误:
ORA-00904:“T2”。“SRC”:无效标识符

这是因为您不能向下引用一个表或别名两级子查询,至少在12c之前是这样的(可能是这样的;有一种说法似乎表明它现在也可以工作了)

您可以使用和
保持密集等级
来实现这一点:

UPDATE tbl2 t2
SET t2.ID = (
  SELECT MIN(t1.ID) KEEP (DENSE_RANK FIRST ORDER BY LENGTH(t1.LABEL) DESC)
  FROM tbl1 t1
  WHERE t2.SRC LIKE t1.LABEL || '%'
);

2 rows updated.

select * from tbl2;

        ID SRC                
---------- --------------------
         2 foo: yeah           
         1 foobar: nope        
您还可以使用
KEEP(densite\u RANK LAST ORDER BY LENGTH(t1.LABEL))
,即
LAST
而不是
FIRST
,并且不使用
DESC
,如果没有空值,这在逻辑上是相同的。

您可以使用
MAX(…)KEEP(densite\u RANK[FIRST\124; LAST]ORDER BY…)
获取最大值,其中的值是
顺序中的第一个(或最后一个)

update tbl2 set tbl2.id =
 (
    with a as (select src, label, 
                      row_number() over (partition by src order by length(label) desc) rn 
               from tbl2 join tbl1 on src like label || '%')
    select id from tbl1 join a using (label) where tbl2.src = a.src and rn = 1
 )
UPDATE tbl2 t2
SET t2.id = ( SELECT MAX( id ) KEEP ( DENSE_RANK LAST
                                      ORDER BY LENGTH( LABEL ) )
              FROM tbl1
              WHERE t2.src LIKE label || '%' );
结果

SELECT * FROM tbl2;

        ID SRC 
---------- -------------
         2 foo: yeah
         1 foobar: nope

这非常有效,让我可以使用一些我以前从未使用过的东西(KEEP,densite\u RANK&FIRST)。谢谢使用MIN(t1.ID)(或MAX(t1.ID))似乎只是因为结果必须聚合,对吗?ID应该只有一个值,而不是选择较小(或最大)的ID值,对吗?这也很有效,但我给了Alex Poole答案,因为他给出了更详细的解释。谢谢哦,不用担心,很乐意帮忙。我毫不在乎这样做是否会完全消除这些“声誉点”——它们只会鼓励匆忙的、没有经过深思熟虑的答案。在数学方面更是如此。祝你好运是的,这和Alex的答案是一样的。亚历克斯先回答了问题,得到了表扬。