Частичное совпадение в базе данных Oracle - PullRequest
0 голосов
/ 27 января 2011

У меня очень большая таблица (более 1 миллиона строк). Эти строки имеют название продукта и цену из разных источников.

Существует много продуктов с одинаковыми названиями, но они отличаются по цене.

Вот проблема,

У нас много раз подряд одни и те же продукты, но их название не будет одинаковым, например

Row    Product name             price
-----  -----------------------  ---- 
Row 1 : XYZ - size information   $a
Row 2. XYZ -Brand information    $b
Row 3. xyz                       $c

Я хочу получить все товары, цена которых отличается. Если имя в строке одинаковое, то я могу легко перейти к самостоятельному соединению в виде Table1.Product_Name = Table1.Product_name и Table1.Price! = Table2.Price

Но в этом случае это не сработает: (

Может кто-нибудь предложить решение для этого?

1 Ответ

3 голосов
/ 27 января 2011

Вы можете попытаться использовать regexp_replace, чтобы пойти в правильном направлении:

create table tq84_products (
  name   varchar2(50),
  price  varchar2( 5)
);

Три продукта:

  • xyz
  • ABCD
  • efghi

, из которых ABCD имеет две записи с одинаковой ценой, а все остальные имеют другую цену.

insert into tq84_products values (' XYZ - size information', '$a');
insert into tq84_products values ('XYZ - brand information', '$b');
insert into tq84_products values ('xyz'                    , '$c');

insert into tq84_products values ('Product ABCD'           , '$d');
insert into tq84_products values ('Abcd is the best'       , '$d');

insert into tq84_products values ('efghi is cheap'         , '$f');
insert into tq84_products values ('no, efghi is expensive' , '$g');

Оператор выбора с стоп-словами для удаления слов, которые обычно встречаются в названиях продуктов.

with split_into_words as (
      select 
        name,
        price,
        upper (
        regexp_replace(name,
                             '\W*'  ||
                       '(\w+)?\W?+' ||
                       '(\w+)?\W?+' ||
                       '(\w+)?\W?+' ||
                       '(\w+)?\W?+' ||
                       '(\w+)?\W?+' ||
                       '(\w+)?\W?+' ||
                       '(\w+)?\W?+' ||
                       '(\w+)?\W?+' ||
                       '(\w+)?'     ||
                       '.*',
                       '\' || submatch.counter
                     ) 
        )                          word
         from
           tq84_products,
           (select
              rownum counter
            from 
              dual
            connect by
              level < 10
           ) submatch
  ),
  stop_words as (
    select 'IS'          word from dual union all
    select 'BRAND'       word from dual union all
    select 'INFORMATION' word from dual 
  )
  select
    w1.price,
    w2.price,
    w1.name,  
    w2.name
--  substr(w1.word, 1, 30)               common_word,
--  count(*) over (partition by w1.name) cnt
  from
    split_into_words w1,
    split_into_words w2
  where
    w1.word   = w2.word and
    w1.name  <  w2.name and
    w1.word is not null and
    w2.word is not null and
    w1.word not in (select word from stop_words) and
    w2.word not in (select word from stop_words) and
    w1.price != w2.price;

Затем выбирается

$a    $b     XYZ - size information                            XYZ - brand information
$b    $c    XYZ - brand information                            xyz
$a    $c     XYZ - size information                            xyz
$f    $g    efghi is cheap                                     no, efghi is expensive

Таким образом, abcd не возвращается, в то время как остальные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...