Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Помогите с запросом  [new]
Sergey_Osipov
Member

Откуда:
Сообщений: 55
Здравствуйте господа.
Вот сижу и туплю над одним запросом.
Есть таблица с комплектами товаров.
with complect as
(
select 1 kod_komp, 2 kod_tov, 1 kol from dual
union 
select 1 kod_komp, 3 kod_tov, 2 kol from dual
union 
select 1 kod_komp, 4 kod_tov, 3 kol from dual
union 
select 2 kod_komp, 3 kod_tov, 1 kol from dual
union 
select 2 kod_komp, 4 kod_tov, 3 kol from dual
union 
select 2 kod_komp, 5 kod_tov, 2 kol from dual
union 
select 3 kod_komp, 2 kod_tov, 1 kol from dual
union 
select 3 kod_komp, 3 kod_tov, 2 kol from dual
union 
select 3 kod_komp, 4 kod_tov, 3 kol from dual
)
select * from complect
Надо найти совпадающие комплекты по товару и количеству.
В данном случае это комплекты 1 и 3.
Можно конечно и процедурку написать, но хочется более красивого решения.
Подкиньте идейку пожалуйста. Может в одну строку их собрать и сравнивать?
6 июн 08, 11:06    [5768923]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с запросом  [new]
Иван Помидоров
Member

Откуда: альянс
Сообщений: 1108
Тоже туплю - может написать
select
t1.*
from
yourtable t1,
yourtable t2
where t1. <что-то>= t2.<что-то> and ....
6 июн 08, 11:10    [5768964]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с запросом  [new]
SimonInBlues
Member

Откуда: Балаково
Сообщений: 264
Sergey_Osipov
Надо найти совпадающие комплекты по товару и количеству.
В данном случае это комплекты 1 и 3.
Можно конечно и процедурку написать, но хочется более красивого решения.
Подкиньте идейку пожалуйста. Может в одну строку их собрать и сравнивать?

не очень надежно но можно так:
with complect as
(
select 1 kod_komp, 2 kod_tov, 1 kol from dual
union 
select 1 kod_komp, 3 kod_tov, 2 kol from dual
union 
select 1 kod_komp, 4 kod_tov, 3 kol from dual
union 
select 2 kod_komp, 3 kod_tov, 1 kol from dual
union 
select 2 kod_komp, 4 kod_tov, 3 kol from dual
union 
select 2 kod_komp, 5 kod_tov, 2 kol from dual
union 
select 3 kod_komp, 2 kod_tov, 1 kol from dual
union 
select 3 kod_komp, 3 kod_tov, 2 kol from dual
union 
select 3 kod_komp, 4 kod_tov, 3 kol from dual
),
m_hash as (
    select 
      t.kod_komp,
      sum(ora_hash(t.kod_tov) + ora_hash(t.kol)) h
    from complect t
    group by t.kod_komp
)
select c.* 
from m_hash t, complect c
where t.h in (
          select m.h
          from m_hash m 
          group by m.h 
          having count(1) > 1
      )
  and c.kod_komp = t.kod_komp
6 июн 08, 11:25    [5769099]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с запросом  [new]
Jannny
Member

Откуда: Спб
Сообщений: 6424
Sergey_Osipov
Подкиньте идейку пожалуйста. Может в одну строку их собрать и сравнивать?
select str, wm_concat(kod_komp)
from
(
SELECT kod_komp
     ,MAX(SYS_CONNECT_BY_PATH(kod_tov||':'||kol,',')) str
FROM   ( SELECT t.*
              , ROW_NUMBER() OVER (PARTITION BY kod_komp ORDER BY kod_tov,kol) rn
         FROM   complect t )
GROUP BY kod_komp
CONNECT BY rn-1 = PRIOR rn AND kod_komp = PRIOR kod_komp
START WITH rn = 1
)
group by str
having count(1) > 1
wm_concat - это извращение, просто не очень понимаю, в каком виде и что надо вернуть.
ЗЫ: собственно и весь пример скорее извращение, хотя если помнить об ограничении длины SYS_CONNECT_BY_PATH, то можно и юзать :)
6 июн 08, 11:30    [5769142]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с запросом  [new]
В поиск
Guest
Всем срочно читать про реляционное деление.
Задача как раз на него...
6 июн 08, 11:36    [5769196]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с запросом  [new]
Elic
Member

Откуда:
Сообщений: 29976
В поиск
Всем срочно читать про реляционное деление.
Задача как раз на него...
А толку-то? Оно реализуется через ж. STFF реляционная алгебра.операция деления.
А в приложении к данной задаче получится вообще монстроидалище.
6 июн 08, 11:48    [5769322]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с запросом  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15487
написать то - не вопрос.. , однако (+1), как выше уже сказали -
монстроидалище, недостойное жить в серьезной базе без
перепроектирования подхода
with complect as
     (select 1 kod_komp, 2 kod_tov, 1 kol from dual
union select 1 kod_komp, 3 kod_tov, 2 kol from dual
union select 1 kod_komp, 4 kod_tov, 3 kol from dual
union select 2 kod_komp, 3 kod_tov, 1 kol from dual
union select 2 kod_komp, 4 kod_tov, 3 kol from dual
union select 2 kod_komp, 5 kod_tov, 2 kol from dual
union select 3 kod_komp, 2 kod_tov, 1 kol from dual
union select 3 kod_komp, 3 kod_tov, 2 kol from dual
union select 3 kod_komp, 4 kod_tov, 3 kol from dual
)
,t1 as (select a.*, count(*) over (partition by kod_komp) ck from complect a)
select a.kod_komp k1,b.kod_komp k2 ,count(*) c
  from t1 a
      ,t1 b
 where a.kod_komp < b.kod_komp
   and a.kod_tov = b.kod_tov
   and a.kol     = b.kol
 group by a.kod_komp 
         ,b.kod_komp
having count(*) = max(a.ck)
   and count(*) = max(b.ck)
;
6 июн 08, 12:09    [5769507]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с запросом  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15487
кстати, хотя на результат это и накак не повлияет, но имхо,
обязательно надо еще условьице добавить ;)
with complect as
     (select 1 kod_komp, 2 kod_tov, 1 kol from dual
union select 1 kod_komp, 3 kod_tov, 2 kol from dual
union select 1 kod_komp, 4 kod_tov, 3 kol from dual
union select 2 kod_komp, 3 kod_tov, 1 kol from dual
union select 2 kod_komp, 4 kod_tov, 3 kol from dual
union select 2 kod_komp, 5 kod_tov, 2 kol from dual
union select 3 kod_komp, 2 kod_tov, 1 kol from dual
union select 3 kod_komp, 3 kod_tov, 2 kol from dual
union select 3 kod_komp, 4 kod_tov, 3 kol from dual
)
,t1 as (select a.*, count(*) over (partition by kod_komp) ck from complect a)
select a.kod_komp k1,b.kod_komp k2 ,count(*) c
  from t1 a
      ,t1 b
 where a.kod_komp < b.kod_komp
   and a.kod_tov = b.kod_tov
   and a.kol     = b.kol
   and a.ck      = b.ck
 group by a.kod_komp 
         ,b.kod_komp
having count(*) = max(a.ck)
   and count(*) = max(b.ck)
;
6 июн 08, 12:14    [5769535]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с запросом  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15487
orawish
кстати, хотя на результат это и накак не повлияет, но имхо,
обязательно надо еще условьице добавить ;)
..
соответственно - его (одного из двух) уже не надобно в having-е
6 июн 08, 12:17    [5769567]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с запросом  [new]
Proteus
Member

Откуда:
Сообщений: 1348
Почти тоже самое только выводятся совпавшие комплекты а не их идентификаторы.

with complect as
(
select 1 kod_komp, 2 kod_tov, 1 kol from dual
union 
select 1 kod_komp, 3 kod_tov, 2 kol from dual
union 
select 1 kod_komp, 4 kod_tov, 3 kol from dual
union 
select 2 kod_komp, 3 kod_tov, 1 kol from dual
union 
select 2 kod_komp, 4 kod_tov, 3 kol from dual
union 
select 2 kod_komp, 5 kod_tov, 2 kol from dual
union 
select 3 kod_komp, 2 kod_tov, 1 kol from dual
union 
select 3 kod_komp, 3 kod_tov, 2 kol from dual
union 
select 3 kod_komp, 4 kod_tov, 3 kol from dual
)
,s2 AS (SELECT COUNT(*) c, c.kod_komp FROM complect c GROUP by c.kod_komp)

SELECT f.kod_komp, f.kod_tov, f.kol, f.kod_komp2, f.kod_tov2, f.kol2
  FROM (SELECT c.kod_komp
              ,c.kod_tov
              ,c.kol
              ,c2.kod_komp kod_komp2
              ,c2.kod_tov kod_tov2
              ,c2.kol kol2
              ,s2.c
              ,COUNT(c.kod_komp) over(PARTITION BY c2.kod_komp, c.kod_komp) c2
          FROM complect c, complect c2, s2
         WHERE c.kod_tov = c2.kod_tov
           AND c.kol = c2.kol
           AND c.kod_komp != c2.kod_komp
           AND c.kod_komp = s2.kod_komp) f
 WHERE f.c = f.c2
   AND kod_komp < kod_komp2
6 июн 08, 12:42    [5769794]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с запросом  [new]
suPPLer
Member

Откуда: Харків, Україна
Сообщений: 7794
Блог
Proteus
           AND c.kod_komp != c2.kod_komp


Можно вместо != поставить <. Чуть поэффективней будет.
6 июн 08, 13:58    [5770493]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с запросом  [new]
Proteus
Member

Откуда:
Сообщений: 1348
suPPLer
Proteus
           AND c.kod_komp != c2.kod_komp


Можно вместо != поставить <. Чуть поэффективней будет.


да, согласен. сам увидел такой вариант после поста 5769535
6 июн 08, 14:04    [5770559]     Ответить | Цитировать Сообщить модератору
 Re: Спасибо.  [new]
Sergey_Osipov
Member

Откуда:
Сообщений: 55
Спасибо.
Помогло.
6 июн 08, 15:59    [5771640]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с запросом  [new]
stax..
Guest
Proteus
Почти тоже самое только выводятся совпавшие комплекты а не их идентификаторы.

Почти такая же задачка
.....
stax
6 июн 08, 17:58    [5772700]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить