Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/77.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
Sql 具有管道符号的Oracle比较表内容_Sql_Oracle - Fatal编程技术网

Sql 具有管道符号的Oracle比较表内容

Sql 具有管道符号的Oracle比较表内容,sql,oracle,Sql,Oracle,我在oracle中遇到以下问题,正在寻找解决方案。 我想比较两个表的内容,但内容格式彼此不同 Table CANON CAN 18102-75|18103-0|18104-88 Table DRUM DR 18103-0 我必须比较这两个表,结果应该是18102-75和18104-88 目前,我有一个简单使用等于的例子,结果很奇怪 CASE WHEN (CANON .CAN = DRUM .DR) THEN NULL -- not showing if they are the

我在oracle中遇到以下问题,正在寻找解决方案。 我想比较两个表的内容,但内容格式彼此不同

Table CANON
CAN
18102-75|18103-0|18104-88

Table DRUM
DR
18103-0
我必须比较这两个表,结果应该是18102-75和18104-88 目前,我有一个简单使用等于的例子,结果很奇怪

CASE WHEN (CANON .CAN =  DRUM .DR) 
    THEN NULL -- not showing if they are the same 
    ELSE  CANON .CAN
END

有些事我不明白

如果同一记录中有更多的值,用|字符分隔,则可以定义(例如)一个PL/SQL函数,用于转换表中的字符串,然后在查询中使用它:

CREATE OR REPLACE TYPE T_CHARACTERS_NESTED_TABLE AS TABLE OF VARCHAR2(10);
/

CREATE OR REPLACE FUNCTION STRING_TO_NESTED_TABLE
(pStringOfCharacters          IN   VARCHAR2)
RETURN T_CHARACTERS_NESTED_TABLE
PIPELINED
AS

   myStringOfCharacters   VARCHAR2(32767)   DEFAULT pStringOfCharacters || '|';
   myPos                  NUMBER;

BEGIN
   LOOP
      myPos := INSTR(myStringOfCharacters, '|');
      EXIT WHEN NVL(myPos, 0) = 0;

      PIPE ROW(TRIM(SUBSTR(myStringOfCharacters, 1, myPos - 1)));

      myStringOfCharacters := SUBSTR(myStringOfCharacters, myPos + 1);
   END LOOP;

   RETURN;

END STRING_TO_NESTED_TABLE;
/
然后:

SELECT CAN
FROM (SELECT T.COLUMN_VALUE AS CAN
      FROM CANON C,
           TABLE(STRING_TO_NESTED_TABLE(C.CAN)) T)
WHERE CAN NOT IN (SELECT DR
                  FROM DRUM
                  WHERE DR IS NOT NULL);

子查询中DR不为NULL的条件会阻止您获取空的结果集,以防DR列中可能有NULL。

这应该可以做到这一点

select *
  from (select substr(can, 1, instr(can, '|', 1, 1) - 1) as can,
               case
                 when level = 1 then
                  replace(substr(can, 1, instr(can, '|', 1, 1)), '|', '')
                 else
                  replace(substr(can,
                                 instr(can, '|', 1, level),
                                 length(can) - instr(can, '|', 1, level)),
                          '|',
                          '')
               end as drum
          from canon
        connect by level <= (length(can) - length(replace(can, '|')))
               and prior sys_guid() is not null
               and prior can = can) x
 where not exists (select 'x' from drum y where y.dr = x.drum)
 order by 1, 2
SQL Fiddle演示:

注意:出于测试目的,我在两个表中的每个表上都添加了第二行,因为我想确保它对2+行有效,因为逻辑对此很敏感

作为对您问题的第二个回答,如果您希望将数据放在同一行上,尽管我认为我的第一个查询更有意义,但这将为您提供您要求的确切结果,即将CAN的每个值的所有值放在同一行上:

select can||'|'||listagg(drum,'|') within group (order by drum) as listed
  from (select substr(can, 1, instr(can, '|', 1, 1) - 1) as can,
               case
                 when level = 1 then
                  replace(substr(can, 1, instr(can, '|', 1, 1)), '|', '')
                 else
                  replace(substr(can,
                                 instr(can, '|', 1, level),
                                 length(can) - instr(can, '|', 1, level)),
                          '|',
                          '')
               end as drum
          from canon
        connect by level <= (length(can) - length(replace(can, '|')))
               and prior sys_guid() is not null
               and prior can = can) x
 where not exists (select 'x' from drum y where y.dr = x.drum)
group by can
order by 1

你总是在寻找佳能里的东西,而不是鼓里的吗?并非相反,也只是为了更好地理解这一点,相机的第一个标识符“18102-75”是否与下两个兼容?它是否会在所有的佳能行上遵循相同的格式;第一个ID是相机,然后是每个由管道隔开的兼容鼓?是的,我想从佳能表中获取数据。有时佳能只有一位数的CAN no。请注意,在结果集中,每个鼓都位于单独的一行。这是因为为了得到您的解决方案,我必须将您的单行拆分为多行,这可能是它们应该如何存储的。如果出于任何原因,必须将它们放在结果集中的同一行上,则可以使用LISTAGG。只是想知道,当有更多管道分隔值时,这会起作用吗?是的,connect by子句用于将行拆分为多行,但应根据每个字符串中管道的数量创建多行。因此,如果在你的例子中,佳能的一排上有5个鼓,那么这一排就有5个鼓了。在下一行中,如果分隔列表中有3个,则为3。