Pregunta

Una combinación cruzada realiza un producto cartesiano en las tuplas de los dos conjuntos.

SELECT *
FROM Table1
CROSS JOIN Table2

¿Qué circunstancias hacen que una operación SQL de este tipo sea particularmente útil?

¿Fue útil?

Solución

Si tienes una " cuadrícula " que desea rellenar por completo, como información de tamaño y color para un artículo de ropa en particular:

select 
    size,
    color
from
    sizes CROSS JOIN colors

Quizás desee una tabla que contenga una fila por cada minuto del día, y desee usarla para verificar que un procedimiento se haya ejecutado cada minuto, por lo que podría cruzar tres tablas:

select
    hour,
    minute
from
    hours CROSS JOIN minutes

O tiene un conjunto de especificaciones de informe estándar que desea aplicar todos los meses del año:

select
    specId,
    month
from
    reports CROSS JOIN months

El problema con el mantenimiento de estos puntos de vista es que, en la mayoría de los casos, no desea un producto completo, especialmente con respecto a la ropa. Puede agregar la lógica MINUS a la consulta para eliminar ciertas combinaciones que no lleva, pero puede que le resulte más fácil rellenar una tabla de otra manera y no usar un producto cartesiano.

Además, podría terminar probando la combinación cruzada en tablas que quizás tengan unas pocas filas más de lo que pensaba, o quizás su cláusula WHERE faltaba parcial o totalmente. En ese caso, su DBA le notificará de inmediato la omisión. Generalmente él o ella no serán felices.

Otros consejos

Normalmente, no querrá un producto cartesiano completo para la mayoría de las consultas de bases de datos. Todo el poder de las bases de datos relacionales es que puede aplicar las restricciones en las que pueda estar interesado para evitar tirar filas innecesarias de la base de datos.

Supongo que hay un ejemplo idóneo en el que podría desearlo si tiene una tabla de empleados y una tabla de trabajos que necesita hacer y quiere ver todas las asignaciones posibles de un empleado a un trabajo.

Generar datos para la prueba.

Ok, esto probablemente no responda a la pregunta, pero, si es cierto (y ni siquiera estoy seguro de eso) es un poco de historia divertido.

En los primeros días de Oracle, uno de los desarrolladores se dio cuenta de que necesitaba duplicar cada fila de una tabla (por ejemplo, es posible que fuera una tabla de eventos y necesitaba cambiarlo por separado "iniciar evento" y " evento final " entradas). Se dio cuenta de que si tenía una tabla con solo dos filas, podría hacer una unión cruzada, seleccionando solo las columnas de la primera tabla, y obtener exactamente lo que necesitaba. Así que creó una tabla simple, a la que, naturalmente, llamó "DUAL "".

Más tarde, necesita hacer algo que solo se puede hacer a través de una selección de una mesa, aunque la acción en sí no tiene nada que ver con la mesa (tal vez olvidó su reloj y quiso leer la hora a través de SELECT SYSDATE DE ...) Se dio cuenta de que todavía tenía su mesa DUAL por ahí, y la usó. Después de un tiempo, se cansó de ver la hora impresa dos veces, por lo que eventualmente eliminó una de las filas.

Otros en Oracle comenzaron a usar su tabla y, finalmente, se decidió incluirla en la instalación estándar de Oracle.

Lo que explica por qué una tabla cuyo único significado es que tiene una fila tiene un nombre que significa " dos " ;.

La clave es " mostrarme todas las combinaciones posibles " ;. Los he usado junto con otros campos calculados y luego ordenados / filtrados.

Por ejemplo, supongamos que está creando una aplicación de arbitraje (trading). Usted tiene vendedores que ofrecen productos a un precio y compradores que solicitan productos a un costo. Realiza una combinación cruzada en la clave del producto (para hacer coincidir a los compradores y vendedores potenciales), calcula la diferencia entre el costo y el precio, luego ordena la desc. en esto para darle a usted (el intermediario) las operaciones más rentables para ejecutar. Casi siempre tendrás otros criterios de filtro de límites, por supuesto.

Toma algo así como una tabla de dígitos, que tiene diez filas para los dígitos 0-9. Puede usar la combinación cruzada en esa tabla varias veces para obtener un resultado que tenga todas las filas que necesite, con los resultados numerados adecuadamente. Esto tiene una serie de usos. Por ejemplo, puede combinarlo con una función datadd () para obtener un conjunto para cada día en un año determinado.

Esta es una forma interesante de usar una combinación cruzada para crear un informe de tabla de referencias . Lo encontré en SQL For Smarties de Joe Celko , y lo he usado varias veces. Se necesita un poco de configuración, pero ha valido la pena el tiempo invertido.

Imagine que tiene una serie de consultas que desea realizar sobre una combinación específica de elementos y fechas (precios, disponibilidad, etc.). Puede cargar los elementos y las fechas en tablas temporales separadas y hacer que sus consultas se unan a las tablas. Esto puede ser más conveniente que la alternativa de enumerar los elementos y las fechas en las cláusulas IN, especialmente porque algunas bases de datos limitan el número de elementos en una cláusula IN.

puedes usarlo CROSS JOIN para: - generar datos para fines de prueba - combine todas las propiedades - necesita todas las combinaciones posibles de, por ejemplo, grupos sanguíneos (A, B, ..) con Rh - / +, etc. - sintonízalo para tus propósitos;) - No soy experto en esta área;)

CREATE TABLE "HR"."BL_GRP_01" 
("GR_1" VARCHAR2(5 BYTE));
REM INSERTING into BL_GRP_01
SET DEFINE OFF;
Insert into BL_GRP_02 (GR_1) values ('A');
Insert into BL_GRP_02 (GR_1) values ('B');
Insert into BL_GRP_02 (GR_1) values ('O');
Insert into BL_GRP_01 (GR_1) values (NULL);

CREATE TABLE "HR"."BL_GRP_02" 
("GR_1" VARCHAR2(5 BYTE));

REM INSERTING into BL_GRP_02
SET DEFINE OFF;
Insert into BL_GRP_02 (GR_1) values ('A');
Insert into BL_GRP_02 (GR_1) values ('B');
Insert into BL_GRP_02 (GR_1) values ('O');
Insert into BL_GRP_02 (GR_1) values (NULL);

CREATE TABLE "HR"."RH_VAL_01" 
("RH_VAL" VARCHAR2(5 BYTE));
REM INSERTING into RH_VAL_01
SET DEFINE OFF;
Insert into RH_VAL_01 (RH_VAL) values ('+');
Insert into RH_VAL_01 (RH_VAL) values ('-');
Insert into RH_VAL_01 (RH_VAL) values (NULL);

select distinct  a.GR_1 || b.GR_1 || c.RH_VAL as BL_GRP
from BL_GRP_01 a, BL_GRP_02 b, RH_VAL_01 c
GROUP BY a.GR_1, b.GR_1, c.RH_VAL;
  • cree una unión para 2 tablas sin un ID común y luego agrúpelas usando max (), etc. para encontrar la combinación más alta posible
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top