2011-01-27 2 views
0

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

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

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

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

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

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

Может любой предложить решение для этого

ответ

3

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

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

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

  • хуг
  • 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 не возвращается в то время как другие.

+0

Я попробую это. – onsy

+0

Это полезно, только одна проблема: «Остановить слова не исправлены в моем случае». – onsy

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