Логически создавать шаблоны на основе таблицы пересечений

Я не уверен, как описать этот вопрос, но я пытаюсь дать предложения о том, какие коды относятся к тарифам. Я делаю это в Oracle.

Вот моя структура базы данных:

CODE (
    CODEID *PK NCHAR(10)
)

CODETARIFF (
    TARIFFNO NCHAR(15) *PK *FK
    CODEID NCHAR(10) *PK *FK
)

TARIFF (
    TARIFFNO NCHAR(15) *PK
)

Поэтому я пытаюсь логически создавать шаблоны, для каких кодов следует назначать тарифы. Я представляю себе что-то вроде: «6 тарифов также связаны с этими двумя кодами»,

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

SELECT COUNT(*), CodeID
FROM CodeTariff
  INNER JOIN (
    SELECT TariffNo, COUNT(*) 
    FROM CodeTariff
    WHERE CodeID IN ('ABC', 'DEF') 
    GROUP BY TariffNo
    HAVING COUNT(*) > 1) SQ 
  ON CodeTariff.TariffNo = SQ.TariffNo 
WHERE CodeID NOT IN ('ABC', 'DEF')
GROUP BY CodeTariff.CodeID
ORDER BY COUNT(*) DESC;

Извините, если это сбивает с толку.

Я не знаю, возможно ли это, но я ищу выход следующим образом:

Данные:     TariffCode

TariffNo        CodeID

1111            ABC
1111            DEF
2222            ABC
2222            DEF
2222            GHI
2222            JKL
3333            ABC
3333            DEF
3333            GHI
3333            JKL

Выход: (если данный тариф 1111)

CodesToAdd      Count

GHI, JKL        2

Чтобы я мог отображать:

2 других тарифа имеют связанные с ними коды GHI и JKL. Вы хотите добавить эти коды в тариф 1111?

0
Возможно, некоторые примеры данных с ожидаемым результатом могут сделать это более ясным?
добавлено автор Tom H, источник
Это правильно? : Последовательность событий: (1) пользователь создает новый тариф; (2) пользователь вводит тариф с некоторыми существующими кодами ( 'ABC' и 'DEF' ); (3) приложение дает пользователю некоторые предложения для других кодов, которые он может захотеть пометить с помощью тарифа. Логика этих предложений заключается в том, что приложение обнаруживает уже существующие тарифы, отмеченные как 'ABC' , так и 'DEF' , и видит, какие другие коды наиболее часто встречаются среди уже существующих тарифов. Если это правильно, то ваш запрос выглядит правильно для меня. , , для каждого кода он показывает, сколько уже существующих тарифов помечено им.
добавлено автор ruakh, источник
Кажется, я вижу. Причина, по которой вы хотите предложить 'GHI' и 'JKL' , заключается не в том, что они each используются по двум тарифам, которые имеют 'ABC' и 'DEF' , но из-за того, что два из них используются вместе по двум тарифам, которые имеют 'ABC' и 'DEF' ?
добавлено автор ruakh, источник
Итак, что бы вы хотели отобразить, если тариф # 3333 также был помечен как MNO?
добавлено автор ruakh, источник
Да, но нет ничего, что говорит о том, что определенное количество тарифов помечено одним или несколькими кодами, нет реальной связи. Я предполагаю, что текущий запрос имеет смысл.
добавлено автор tedski, источник
Да это верно
добавлено автор tedski, источник

2 ответы

Попробуйте эти волшебники:

SELECT     Code, COUNT(*) AS Count
FROM         (SELECT     dbo.TariffCode.Tariff, dbo.TariffCode.Code
                   FROM          dbo.TariffCode LEFT OUTER JOIN
                                              (SELECT     TariffCode_2.Tariff, TariffCode_2.Code
                                                FROM          dbo.TariffCode AS TariffCode_2 INNER JOIN
                                                                           (SELECT     Tariff, Code
                                                                             FROM          dbo.TariffCode AS TariffCode_1
                                                                             WHERE      (Tariff = '1111')) AS TariffsWithSharedCodes ON TariffCode_2.Code = TariffsWithSharedCodes.Code AND 
                                                                       TariffCode_2.Tariff <> '1111') AS MutualCodes ON dbo.TariffCode.Tariff = MutualCodes.Tariff AND 
                                          dbo.TariffCode.Code = MutualCodes.Code
                   WHERE      (MutualCodes.Code IS NULL) AND (dbo.TariffCode.Tariff <> '1111')) AS MissingCodes
GROUP BY Code
ORDER BY Count DESC, Code

Это T-SQL, извините, но вы получите идею

0
добавлено

Надеюсь, приведенный ниже сценарий поможет вам. Он получит все возможные тарифы не только для «1111»:

with temp as (
  select tariffno, tariffno2, codeid 
  from (
    select distinct c1.tariffno, c2.tariffno as tariffno2, c2.codeid
    from tariffcode c1
    join tariffcode c2 on c1.tariffno != c2.tariffno and c1.codeid != c2.codeid 
  ) c1 
  where 
    not exists (select 1 from tariffcode where tariffno = c1.tariffno and codeid = c1.codeid)
)
select tariffno, codeid, count(*) as cnt from temp group by tariffno, codeid;
0
добавлено
SqlCom.ru - Стиль жизни SQL
SqlCom.ru - Стиль жизни SQL
908 участник(ов)

Правила чата - https://t.me/sqlcom/88269 @sqlcom - основной канал (только MS SQL) @sql_ninja - второй канал (SQL вопросы начального уровня и свободное общение) @Gopnegbot - Викторина по SQL Server (наберите в привате /quiz). Предложения в @sql_ninja

SQL_Ninja
SQL_Ninja
340 участник(ов)

Правила чата - https://t.me/sqlcom/88269 @sqlcom - основной канал (только SQL) @sql_ninja - второй канал (SQL вопросы начального уровня и свободное общение) @Gopnegbot - Викторина по SQL Server (наберите в привате /quiz)

Oracle RU
Oracle RU
303 участник(ов)

Русскоязычная группа по Oracle. — Архитектура СУБД — PL/SQL — Оптимизация — Администрирование — Вакансии Oracle (указать инфу по вилке ЗП и удалёнке) Приглашайте коллег :-) Запрещены: личные оскорбления, обсуждения оффтопик вопросов политики и религии