Crear lógicamente plantillas basadas en tabla de intersección.

No estoy seguro de cómo describir la pregunta, pero estoy tratando de dar sugerencias sobre qué códigos atribuir a las tarifas. Estoy haciendo esto en Oracle.

Aquí está mi estructura de base de datos:

CODE (
    CODEID *PK NCHAR(10)
)

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

TARIFF (
    TARIFFNO NCHAR(15) *PK
)

Así que estoy tratando de hacer lógicamente plantillas para qué códigos deberían asignarse a las tarifas. Me imagino mostrando algo como: "6 tarifas también tienen estos 2 códigos asociados con ellos"

Intenté esto, pero los recuentos que se devuelven para cada uno de los códigos no muestran realmente una plantilla, solo muestran incidencias de cuándo aparece ese código con los dos que he especificado.

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;

Perdón si esto es confuso.

No sé si esto es posible, pero estoy buscando una salida como esta:

Datos:     Codigo de Tarifa

TariffNo        CodeID

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

Salida: (cuando se le da tarifa 1111)

CodesToAdd      Count

GHI, JKL        2

Para que pueda mostrar:

Otras 2 tarifas tienen los códigos GHI y JKL asociados. ¿Le gustaría agregar estos códigos a la tarifa 1111?

0
Tal vez algunos datos de muestra con el resultado esperado podrían aclarar esto?
agregado el autor Tom H, fuente
¿Es esto correcto? : La secuencia de eventos es: (1) el usuario crea una nueva tarifa; (2) el usuario etiqueta la tarifa con algunos códigos existentes ( 'ABC' y 'DEF' ); (3) la aplicación le da al usuario algunas sugerencias para otros códigos con los que podría querer etiquetar la tarifa. La lógica de estas sugerencias es que la aplicación encuentra tarifas ya existentes que están etiquetadas con 'ABC' y 'DEF' , y ve qué otros códigos se encuentran más comúnmente Entre esas tarifas ya existentes. Si eso es correcto, entonces tu consulta me parece correcta. . . Para cada código, muestra cuántas tarifas existentes están etiquetadas con él.
agregado el autor ruakh, fuente
Creo que ya veo. La razón por la que desea sugerir 'GHI' y 'JKL' no es que sean cada una usadas en dos tarifas que tienen 'ABC' y 'DEF' , pero como los dos se usan juntos en dos tarifas que tienen 'ABC' y 'DEF' ?
agregado el autor ruakh, fuente
Entonces, ¿qué le gustaría mostrar si la tarifa # 3333 también se etiquetara como MNO?
agregado el autor ruakh, fuente
Sí, pero no hay nada que diga que un cierto número de tarifas estén etiquetadas con uno o más códigos, no hay un vínculo real. Supongo que la consulta actual tiene sentido sin embargo.
agregado el autor tedski, fuente
Si, eso es correcto
agregado el autor tedski, fuente

2 Respuestas

Prueba estas magias:

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

Esto es T-SQL, lo siento, pero tendrás la idea

0
agregado

Espero que el guión de abajo te pueda ayudar. Obtendrá todas las tarifas posibles, no solo para '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
agregado