Dividir consultas

 

Hay ocasiones en las que no se puede, o no sabemos, hacer una consulta.

Tenemos clara la consulta, creemos que va a funcionar, pero no es así y nos vemos obligados a realizar una consulta ‘auxiliar’ que puesta en una nueva consulta nos da los resultados que esperamos.

 

A mi me suele pasar, sobre todo, con las consultas de totales.

 

Supongamos que tenemos la siguiente tabla:

 

Movimientos

FechaMovimiento

CodigoCliente

Referencia

Monto

12/06/2009

5223

VENTA

1000

18/06/2009

5223

PAGO

-150

24/06/2009

5223

PAGO

-80

28/06/2009

5223

PAGO

-120

30/06/2009

5223

PAGO

-100

12/06/2009

8888

VENTA

1000

18/06/2009

8888

PAGO

-10

24/06/2009

8888

PAGO

-90

28/06/2009

8888

PAGO

-120

30/06/2009

8888

PAGO

-110

02/07/2009

8888

PAGO

-80

12/07/2009

8888

PAGO

-100

 

Con el campo FechaMovimiento de tipo fecha, el campo Monto de tipo numérico, y los otros dos tipo texto.

 

Supongamos que quiero obtener los registros del último pago de cada cliente, es decir:

 

UltimosPagos

CodigoCliente

LaFecha

Referencia

Monto

5223

30/06/2009

PAGO

-100

8888

12/07/2009

PAGO

-100

 

Pensando en una consulta de totales monto la siguiente consulta:

 

 

SELECT Movimientos.CodigoCliente, Max(Movimientos.FechaMovimiento) AS LaFecha

FROM Movimientos

WHERE (((Movimientos.Referencia)="pago"))

GROUP BY Movimientos.CodigoCliente;

 

Que ya me devuelve la ultima fecha de pago de cada cliente:

 

Auxiliar

CodigoCliente

LaFecha

5223

30/06/2009

8888

12/07/2009

 

Ahora pienso que con añadir los campos referencia y Monto tendré mi problema resuelto pero NO soy capaz de poner esos campos en la consulta de totales.

 

Llegados a este punto decido guardar la consulta anterior como Auxiliar y hacer una nueva consulta como la siguiente:

 

 

SELECT Auxiliar.CodigoCliente, Auxiliar.LaFecha, movimientos.Referencia, movimientos.Monto

FROM Auxiliar INNER JOIN movimientos ON (Auxiliar.CodigoCliente = movimientos.CodigoCliente) AND (Auxiliar.LaFecha = movimientos.FechaMovimiento);

 

Que me devuelve los resultados esperados.

 

 

Consultas anidadas

 

Hasta aquí todo bien, pero si la Auxiliar solo la usamos para hacer la consulta definitiva, podemos poner la SQL de Auxiliar dentro de la consulta final, eliminar la consulta Auxiliar y quedarnos solo con una consulta.

 

Veamos como ponemos la SQL de una consulta dentro de otra.

 

Para que la explicación sea más sencilla supongamos la siguiente consulta

 

SELECT Tabla1.Campo1, Tabla1.Campo2
FROM Tabla1;

 

que llamo Auxiliar

 

Supongamos que la consulta Auxiliar solo la uso para la siguiente consulta

 

SELECT Auxiliar.Campo1
FROM Auxiliar;

 

En este caso, la segunda consulta podemos modificarla como sigue

 

SELECT Auxiliar.Campo1

FROM (SELECT Tabla1.Campo1, Tabla1.Campo2

FROM Tabla1) as Auxiliar;

 

y podemos borrar la consulta Auxiliar.

 

Observad que lo que hemos hecho ha sido poner en el FROM y delante del nombre de la consulta

 

(La SQL de la consulta auxiliar sin el ; final) AS

 

Paréntesis, la SQL de la consulta auxiliar sin el ; final, paréntesis, y AS

 

Volviendo a nuestras consultas iniciales teníamos

 

Auxiliar

 

SELECT Movimientos.CodigoCliente, Max(Movimientos.FechaMovimiento) AS LaFecha

FROM Movimientos

WHERE (((Movimientos.Referencia)="pago"))

GROUP BY Movimientos.CodigoCliente;

 

Consulta UltimosPagosConAuxiliar:

 

SELECT Auxiliar.CodigoCliente, Auxiliar.LaFecha, movimientos.Referencia, movimientos.Monto

FROM Auxiliar INNER JOIN movimientos ON (Auxiliar.CodigoCliente = movimientos.CodigoCliente) AND (Auxiliar.LaFecha = movimientos.FechaMovimiento);

 

Siguiendo las indicaciones anteriores podemos tener una única consulta que he llamado UltimosPagosDirecta:

 

SELECT [Auxiliar].CodigoCliente, [Auxiliar].LaFecha, movimientos.Referencia, movimientos.Monto

FROM (SELECT Movimientos.CodigoCliente, Max(Movimientos.FechaMovimiento) AS LaFecha

FROM Movimientos

WHERE (((Movimientos.Referencia)="pago"))

GROUP BY Movimientos.CodigoCliente) as Auxiliar INNER JOIN movimientos ON ([Auxiliar].LaFecha=movimientos.FechaMovimiento) AND ([Auxiliar].CodigoCliente=movimientos.CodigoCliente);

 

 

Aviso importante

 

Si tenemos una consulta como la que he indicado

 

SELECT Auxiliar.Campo1

FROM (SELECT Tabla1.Campo1, Tabla1.Campo2

FROM Tabla1) as Auxiliar;

 

al guardarla, Access la transforma dejándola como sigue

 

SELECT Auxiliar.Campo1

FROM [SELECT Tabla1.Campo1, Tabla1.Campo2

FROM Tabla1]. AS Auxiliar;

 

Access cambia los corchetes por paréntesis y añade un punto.

 

Con esta sintaxis la consulta sigue funcionando bien pero en ocasiones, si posteamos esta SQL con corchetes y punto y alguien la copia en una nueva consulta NO FUNCIONA.

 

¿Qué hacer si nos proponen una consulta con corchetes y punto y no funciona?

 

Cambiar los corchetes por paréntesis y quitar el punto.

Add your content here