2012-08-22 12 views
7

Esta es una consulta reducida de mi problema mayor, pero la esencia es que estoy tratando de unirme internamente a una selección donde la selección está limitada por la selección externa. ¿Es eso posible? Recibo un error sobre el identificador de varias piezas S.Item y S.SerialNum en la selección interna.Unión interna a una instrucción select donde la cláusula where de la instrucción de selección interna hace referencia a la selección externa?

Lo esencial es esto, tenemos que agrupar por el artículo/serie, y la consulta es lo suficientemente grande, no queremos volver atrás y agrupar todo en la consulta completa para esta unión menor.

SELECT S.Item, S.SerialNum, S.ReceiveDate 
    FROM SALES S 
    INNER JOIN (SELECT W.Item, W.SerialNum, MIN(W.SalesDate) 
        FROM WARRANTY W 
        WHERE W.Item  = S.Item AND 
          W.SerialNum = S.SerialNum 
        GROUP BY Item, SerialNum, SalesDate) WW 
     ON S.Item = WW.Item AND WW.SerialNum 
+1

No estoy muy seguro de lo que estás pidiendo aquí .. pero desde el aspecto de esa consulta, quite su interior 'DONDE W.Item .. .' cláusula e incluir eso en la declaración 'ON'. Las combinaciones internas hacen automáticamente lo que parece que su cláusula 'WHERE' está tratando de hacer ... – StuckAtWork

+0

Su consulta externa no hace referencia a ninguna variable en la consulta interna. Entonces, solo está actuando como un filtro. ¿Pretendías incluir minSalesDate en la consulta externa? –

+0

@GordonLinoff. Tenía la intención de incluir eso, whoops. Mano tecleó la consulta. –

Respuesta

13

Parece que tiene su referencia JOIN en el lugar equivocado.

SELECT S.Item, S.SerialNum, S.ReceiveDate 
FROM SALES S 
INNER JOIN 
(
    SELECT W.Item, W.SerialNum, MIN(W.SalesDate) MinSalesDate 
    FROM WARRANTY W 
    GROUP BY Item, SerialNum 
) WW 
     ON S.Item = WW.Item 
     AND S.SerialNum = WW.SerialNum 

Editar, basado en su comentario sobre el filtrado, se puede colocar una cláusula WHERE en su interior SELECT:

SELECT S.Item, S.SerialNum, S.ReceiveDate, WW.MinSalesDate 
FROM SALES S 
INNER JOIN 
(
    SELECT W.Item, W.SerialNum, MIN(W.SalesDate) MinSalesDate 
    FROM WARRANTY W 
    WHERE yourFilter here 
    GROUP BY Item, SerialNum 
) WW 
     ON S.Item = WW.Item 
     AND S.SerialNum = WW.SerialNum 
+2

También 'SalesDate' no debe estar en' GROUP BY' y 'MIN (W.SalesDate)' necesita un alias. –

+0

@MartinSmith corregido, gracias – Taryn

+0

Así que no puedo poner una cláusula 'where' en la declaración' select' interior? El propósito es que algunos de los resultados tienen un estado "caducado", así que agregué 'MIN (EXPIRED)' e hice un 'group by' sobre él, luego uní me a' ON EXPIRED = 0'. Me pregunto si hay otros más complicados en los que no podré hacer eso. –

2

Puede probar un common_table_expression también en lugar de un JOIN. Check the WITH clause here.

Podría ser algo como esto:

WITH Warranty_CTE (Item, SerialNum, MinSalesDate) 
AS 
(
SELECT W.Item, W.SerialNum, MIN(W.SalesDate) MinSalesDate 
    FROM WARRANTY W 
    GROUP BY Item, SerialNum 
) 
SELECT S.Item, S.SerialNum, S.ReceiveDate 
FROM SALES S 
INNER JOIN Warranty_CTE WC 
     ON S.Item = WC.Item 
     AND S.SerialNum = WC.SerialNum 
+0

También daré una oportunidad. Creo que lo conseguí trabajando desde arriba –

+0

Jot a NOTA sobre el plan de ejecución de esta solución: El plan de esta solución debe ser el mismo que la solución de bluefeet. (Así que en el fondo es el mismo proceso del optimizador) Pero creo que esta afirmación es más legible. –

+0

Me gusta la solución más fácil de leer. ¿Es esto algo más lento? –

Cuestiones relacionadas