Как получить количество реестров в таблице, которые точно соответствуют характеристикам другого реестра в другой таблице? - PullRequest
1 голос
/ 16 февраля 2011

Это проблема, которая поставила меня в тупик на несколько дней. Я не настолько опытен в SQL, поэтому потерпите меня, если это кажется очевидным.

У меня есть две таблицы, одна с ингредиентами, немного похожими на:

ITEM     INGREDIENTS
-----    -------------
A01      Ing-01
A01      Ing-02
A01      Ing-03
A02      Ing-01
A02      Ing-03
A02      Ing-05
A03      Ing-02
A03      Ing-12
A03      Ing-22
 . 
 . 
 . 
A99      Ing-04

Так, скажем, предмет А01 имеет определенный набор из трех ингредиентов.

А затем есть еще одна таблица, намного больше, которая включает такую ​​информацию:

PACK      INGREDIENTS
-----     ------------
AAA       Ing-01
AAA       Ing-02
AAA       Ing-03
ABB       Ing-72
ABB       Ing-74
ABB       Ing-81
BCC       Ing-01
BCC       Ing-02
BCC       Ing-07
 . 
 . 
 . 
ZQY       Ing-02

Проблема в том, что мне нужен быстрый способ определить, сколько упаковок содержит именно ингредиенты для данного предмета. До сих пор мне нужно было выполнить запрос, чтобы найти набор ингредиентов для данного предмета, а затем выполнить отдельный запрос, чтобы подсчитать количество упаковок, в которых ТОЧНО этого набора ингредиентов. Итак, я пытаюсь собрать один запрос, который дает мне эту информацию.

Проблема становится более сложной, потому что в некоторых отдельных случаях мне может понадобиться узнать, сколько пакетов имеют ПО НАИМЕНЬШЕМУ двух компонентов, поэтому мне нужно построить запрос так, чтобы мне нужно было измените его минимально, чтобы получить результаты.

Возможно ли это вообще или я перехватываю? Любая помощь и предложения будут высоко оценены.

С уважением,

1 Ответ

1 голос
/ 16 февраля 2011

, если мы предположим, что все предметы сделаны из трех ингредиентов, а во всех упаковках тоже есть три ингредиента, вы можете легко найти совпадения между упаковками и предметами по этому запросу:

SQL> SELECT p.pack, i.item, COUNT(*)
  2    FROM pack p
  3    JOIN item i ON p.ingredient = i.ingredient
  4   GROUP BY p.pack, i.item
  5  HAVING COUNT(*) >= 3;

PACK ITEM   COUNT(*)
---- ---- ----------
AAA  A01           3

Вы можете заменить константу 3 в запросе на 2, чтобы найти пакеты, которые имеют как минимум 2 общих компонента с элементами:

SQL> SELECT p.pack, i.item, COUNT(*)
  2    FROM pack p
  3    JOIN item i ON p.ingredient = i.ingredient
  4   GROUP BY p.pack, i.item
  5  HAVING COUNT(*) >= 2;

PACK ITEM   COUNT(*)
---- ---- ----------
BCC  A01           2
AAA  A01           3
AAA  A02           2

Если количество ингредиентов неизвестно, этот запрос вернет точные совпадения:

SQL> SELECT p.pack, i.item, COUNT(*)
  2    FROM (SELECT pack, ingredient,
  3                 COUNT(*) over (PARTITION BY pack) ingredients#
  4            FROM pack) p
  5    JOIN (SELECT item, ingredient,
  6                 COUNT(*) over (PARTITION BY item) ingredients#
  7            FROM item) i ON p.ingredient = i.ingredient
  8                        AND p.ingredients# = i.ingredients#
  9   GROUP BY p.pack, i.item, i.ingredients#
 10  HAVING COUNT(*) = i.ingredients#;

PACK ITEM   COUNT(*)
---- ---- ----------
AAA  A01           3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...