2014-11-07 2 views
0

У меня есть два столбца в двух разных таблицах и вы хотите сравнить строковые значения. Например:Сравнение двух разных строк в SQL, которые находятся в другом порядке

TABLE1.COLUMNA value = ABC, DEF, XYZ 
TABLE2.COLUMNB value = ABC, XYZ, DEF 

Я хочу вернуть результаты, когда две строки не равны. В этом случае я не забочусь о том, что все, что мне нужно, это то, что эти два значения равны. Таким образом, в приведенном выше примере две строки равны.

Эти две строки не будут равны

TABLE1.COLUMNA value = ABC, DEF, XYZ 
TABLE2.COLUMNB value = ABC, XYZ, LMN 

FYI ... Я помещаю этот запрос в инструмент, который поддерживает только только запросы SQL.

Любая помощь будет оценена по достоинству.

+1

Трудно сделать это в одном запросе, и именно поэтому вы не должны хранить значения, разделенные запятыми, в одном поле. Основной проблемой является разделение строки, что само по себе достаточно сложно. См. [Http://stackoverflow.com/questions/3710589/is-there-a-function-to-split-a-string-in-plsql](http://stackoverflow.com/questions/3710589/is-there -a-функции к сплит-а-строки-в-PLSQL). – GolezTrol

+1

Ну, это то, что происходит, когда вы используете строки для хранения списков вещей. SQL имеет эту отличную структуру данных для списков, ее называют «таблицей». У Oracle даже есть вложенные таблицы - навсегда изгоняющие самую меру мысль о хранении вещей в списке от любого, кто использует базу данных. Узнайте о соединительных таблицах. –

+0

Можете ли вы написать хранимые процедуры или функции? Затем вы можете: 1) проанализировать каждое значение столбца 2) сохранить каждое значение в новой таблице темпа.Сравнение временных таблиц с соединением (так ABC соединяется с ABC и т. Д.) Даст вам какие-либо различия между таблицами, то есть столбцы с разделителями значений – Grantly

ответ

1

Это ужасный, ужасный способ хранения списков. Но у Oracle есть эта удивительная вещь, называемая регулярными выражениями, и они позволят вам сделать это. Чтобы получить освежитель на них, попробуйте запустить это:

with t as (
     select '((a,)|(c,)|(b,)){3}' as pat from dual 
    ) 
select pat, (case when regexp_like('a,b,c' ||',', pat) then 1 else 0 end) 
from t; 

Это возвращает истину, - приводит к выводу, что мы можем ухудшать строку, чтобы превратить его в регулярное выражение, чтобы получить совпадение по элементам в другой строке. Для полного равенства мы хотим сделать сравнение в обоих направлениях.

Итак, вот код, который, кажется, чтобы решить вашу проблему:

with t as (
     select 'ABC,DEF,XYZ' as val1, 'ABC,XYZ,DEF' as val2 from dual union all 
     select 'ABC,DEF,XYZ', 'ABC,XYZ,LMN' from dual 
    ) 
select t.*, 
     (case when regexp_like(val1 || ',', pat2||'{'||val2_len||'}') and 
        regexp_like(val2 || ',', pat1||'{'||val1_len||'}') 
      then 1 else 0 
     end) as comp 
from (select t.*, 
      replace('((' || replace(val1 || ',', ',', ',)|(')||'))', '|())', ')') as pat1, 
      replace('((' || replace(val2 || ',', ',', ',)|(')||'))', '|())', ')') as pat2, 
      length(val1) - length(replace(val1, ',', '')) + 1 as val1_len, 
      length(val2) - length(replace(val2, ',', '')) + 1 as val2_len 
     from t 
    ) t ; 

Это может не сработать, если у вас есть повторяющиеся значения в списке. Но, повторяю, использование таблиц соединений или вложенных таблиц - правильный способ хранения этой информации. Не строковые кодированные списки.

0
  1. РАЗДЕЛИТЬ Каждая строка С ИСПОЛЬЗОВАНИЕМ DELIMINATOR (,) на 3 короткой строки LIKE 'ABC' 'DEF' 'XYZ'
  2. хранить эти 3 коротких строки в другой таблице.
  3. использовать, например,

SELECT *

ОТ (SELECT * FROM TABLE1

EXCEPT 

    SELECT * FROM TABL2) 

, если результат равен NULL, ТОГДА 'РАВНО'

использовать эту функцию, чтобы разделить

CREATE FUNCTION [dbo].[fnSplitString] 
( 
    @string NVARCHAR(MAX), 
    @delimiter CHAR(1) 
) 
RETURNS @output TABLE(splitdata NVARCHAR(MAX) 
) 
BEGIN 
    DECLARE @start INT, @end INT 
    SELECT @start = 1, @end = CHARINDEX(@delimiter, @string) 
    WHILE @start < LEN(@string) + 1 BEGIN 
     IF @end = 0 
      SET @end = LEN(@string) + 1 

     INSERT INTO @output (splitdata) 
     VALUES(SUBSTRING(@string, @start, @end - @start)) 
     SET @start = @end + 1 
     SET @end = CHARINDEX(@delimiter, @string, @start) 

    END 
    RETURN 
END 
Смежные вопросы