Super query sobre Northwind

Antiguamente, en mis clases en UPIITA el profesor Carlos de la Cruz había pedido un query sobre la base de datos Northwind que nos devolviera las órdenes que tuvieran dos productos iguales, en aquel momento no pude hacerlo (t_t), pero ahora que lo ha vuelto a pedir en el grupo de mi maigo @Rosend_mc, me lo tomé personal y aquí está.

La consulta nos regresará pares de órdenes, con al menos dos productos iguales, sé que es enooorme y que seguro hay una solución mejor pero como siempre digo: por algo se empieza. Dejo el Script en SQL y un PDF en el que intento explicar los detalles de la consulta.

Descargar PDF con la explicación
SELECT DISTINCT O1.Or1
 ,O2.Or2
FROM (
 SELECT OD1.OrderID Or1
  ,OD2.OrderId Or2
  ,OD1.ProductID
  ,OD2.ProductID P1
 FROM [Order Details] OD1
 INNER JOIN [Order Details] OD2
  ON OD1.ProductID = OD2.ProductID
   AND OD1.OrderID <> OD2.OrderID
 WHERE OD1.OrderID IN (
   SELECT OD.OrderID
   FROM [Order Details] OD
   GROUP BY OD.OrderID
   HAVING COUNT(OD.ProductID) >= 2
   )
  AND OD2.OrderID IN (
   SELECT OD.OrderID
   FROM [Order Details] OD
   GROUP BY OD.OrderID
   HAVING COUNT(OD.ProductID) >= 2
   )
 ) O1
INNER JOIN (
 SELECT OD1.OrderID Or1
  ,OD2.OrderId Or2
  ,OD1.ProductID
  ,OD2.ProductID P2
 FROM [Order Details] OD1
 INNER JOIN [Order Details] OD2
  ON OD1.ProductID = OD2.ProductID
   AND OD1.OrderID <> OD2.OrderID
 WHERE OD1.OrderID IN (
   SELECT OD.OrderID
   FROM [Order Details] OD
   GROUP BY OD.OrderID
   HAVING COUNT(OD.ProductID) >= 2
   )
  AND OD2.OrderID IN (
   SELECT OD.OrderID
   FROM [Order Details] OD
   GROUP BY OD.OrderID
   HAVING COUNT(OD.ProductID) >= 2
   )
 ) O2
 ON O1.Or1 = O2.Or1
  AND O1.Or2 = O2.Or2
  AND O1.P1 <> O2.P2

Si lo mejoran no duden en pasarme su script.


¡Saludos!
@fferegrino :)

6 comments:

  1. select od1.OrderID, od2.OrderID
    from [Order Details] od1 inner join [Order Details] od2 on od1.ProductID = od2.ProductID
    group by od1.OrderID, od2.OrderID
    having COUNT(od1.OrderID) >1 and COUNT(od2.OrderID) >1 and od1.OrderID != od2.OrderID
    :D

    ReplyDelete
  2. Parece que no es necesario el COUNT(od2.OrderID)>1 ya que como es un self join va a filtrar los resultados con el COUNT(od1.OrderID)>1

    ReplyDelete
  3. Excelente ;) y sin tanto subquery.

    No puedo corroborarlo ahora, pero no sé si esta parte esté correcta: "having COUNT(od1.OrderID) >1".

    ReplyDelete
  4. Tal vez sea:

    COUNT(od1.ProductID) >1

    ReplyDelete
  5. select o1.OrderID,o2.OrderID
    from [Order Details] as o1
    inner join [Order Details] as o2
    on o1.ProductID=o2.ProductID
    group by o1.OrderID,o2.OrderID
    having COUNT(*)=2

    dice igual a dos, no mas de un producto igual (Y)

    ReplyDelete

¡Hey, gracias por tu comentario! No seas anónimo, inicia sesión para que te responda más fácilmente.