Consultas de Referencias Cruzadas (Access)
Una consulta de referencias cruzadas es aquella que nos permite visualizar
los datos en filas y en columnas, estilo tabla, por ejemplo:
| Producto / Año |
1996 |
1997 |
| Pantalones |
1.250 |
3.000 |
| Camisas |
8.560 |
1.253 |
| Zapatos |
4.369 |
2.563 |
Si tenemos una tabla de productos y otra tabla de pedidos, podemos
visualizar en total de productos pedidos por año para un artículo determinado,
tal y como se visualiza en la tabla anterior. La sintaxis para este tipo de consulta es la siguiente:
TRANSFORM función agregada instrucción select PIVOT campo pivot
[IN (valor1[, valor2[, ...]])]
En donde:
- función agregada
- Es una función SQL agregada que opera sobre los datos seleccionados.
- instrucción select
- Es una instrucción SELECT.
- campo pivot
- Es el campo o expresión que desea utilizar para crear las cabeceras de la
columna en el resultado de la consulta.
- valor1, valor2
- Son valores fijos utilizados para crear las cabeceras de la columna.
Para resumir datos utilizando una consulta de referencia cruzada, se
seleccionan los valores de los campos o expresiones especificadas como cabeceras
de columnas de tal forma que pueden verse los datos en un formato más compacto
que con una consulta de selección.
TRANSFORM es opcional pero si se incluye es
la primera instrucción de una cadena SQL. Precede a la instrucción
SELECT que especifica los campos utilizados como
encabezados de fila y una cláusula GROUP BY que
especifica el agrupamiento de las filas. Opcionalmente puede incluir otras
cláusulas como por ejemplo WHERE, que especifica
una selección adicional o un criterio de ordenación.
Los valores devueltos en campo pivot se utilizan como encabezados de
columna en el resultado de la consulta. Por ejemplo, al utilizar las cifras de
ventas en el mes de la venta como pivot en una consulta de referencia cruzada
se crearían 12 columnas. Puede restringir el campo pivot para crear encabezados
a partir de los valores fijos (valor1, valor2) listados en la cláusula opcional
IN.
También puede incluir valores fijos, para los que no existen datos, para
crear columnas adicionales.
Ejemplos
TRANSFORM Sum(Cantidad) AS Ventas SELECT Producto, Cantidad FROM
Pedidos WHERE Fecha Between #01-01-98# And #12-31-98# GROUP BY Producto
ORDER BY Producto PIVOT DatePart("m", Fecha);
- Crea una consulta de tabla de referencias cruzadas que muestra las ventas
de productos por mes para un año específico. Los meses aparecen de izquierda a
derecha como columnas y los nombres de los productos aparecen de arriba hacia
abajo como filas.
TRANSFORM Sum(Cantidad) AS Ventas SELECT Compania FROM Pedidos
WHERE Fecha Between #01-01-98# And #12-31-98# GROUP BY Compania
ORDER BY Compania PIVOT "Trimestre " & DatePart("q", Fecha) In ('Trimestre1',
'Trimestre2', 'Trimestre 3', 'Trimestre 4');
- Crea una consulta de tabla de referencias cruzadas que muestra las ventas
de productos por trimestre de cada proveedor en el año indicado. Los trimestres
aparecen de izquierda a derecha como columnas y los nombres de los proveedores
aparecen de arriba hacia abajo como filas.
Un caso práctico:
Se trata de resolver el siguiente problema: tenemos una tabla de productos
con dos campos, el código y el nombre del producto, tenemos otra tabla de
pedidos en la que anotamos el código del producto, la fecha del pedido y la
cantidad pedida. Deseamos consultar los totales de producto por año, calculando
la media anual de ventas.
Estructura y datos de las tablas:
1. Artículos:
| ID |
Nombre |
| 1 |
Zapatos |
| 2 |
Pantalones |
| 3 |
Blusas |
2. Pedidos:
| Id |
Fecha |
Cantidad |
| 1 |
11/11/1996 |
250 |
| 2 |
11/11/1996 |
125 |
| 3 |
11/11/1996 |
520 |
| 1 |
12/10/1996 |
50 |
| 2 |
04/05/1996 |
250 |
| 3 |
05/08/1996 |
100 |
| 1 |
01/01/1997 |
40 |
| 2 |
02/08/1997 |
60 |
| 3 |
05/10/1997 |
70 |
| 1 |
12/12/1997 |
8 |
| 2 |
15/12/1997 |
520 |
| 3 |
17/10/1997 |
1250 |
Para resolver la consulta planteamos la siguiente consulta:
TRANSFORM Sum(Pedidos.Cantidad) AS Resultado SELECT Nombre AS Producto,
Pedidos.Id AS Código, Sum(Pedidos.Cantidad) AS TOTAL, Avg(Pedidos.Cantidad)
AS Media FROM Pedidos INNER JOIN Artículos ON Pedidos.Id = Artículos.Id
GROUP BY Pedidos.Id, Artículos.Nombre PIVOT Year(Fecha);
y obtenemos el siguiente resultado:
| Producto |
Código |
TOTAL |
Media |
1996 |
1997 |
| Zapatatos |
1 |
348 |
87 |
300 |
48 |
| Pantalones |
2 |
955 |
238,75 |
375 |
580 |
| Blusas |
3 |
1940 |
485 |
620 |
1320 |
Comentarios a la consulta:
La clásula TRANSFORM indica el valor que
deseamos visualizar en las columnas que realmente pertenecen a la consulta, en
este caso 1996 y 1997, puesto que las demás columnas son opcionales.
SELECT especifica el nombre de las columnas
opcionales que deseamos visualizar, en este caso Producto, Código, Total y
Media, indicando el nombre del campo que deseamos mostrar en cada columna o el
valor de la misma. Si incluimos una función de cálculo el resultado se hará en
base a los datos de la fila actual y no al total de los datos.
FROM especifica el origen de los datos. La
primera tabla que debe figurar es aquella de donde deseamos extraer los datos,
esta tabla debe contener al menos tres campos, uno para los títulos de la fila,
otros para los títulos de la columna y otro para calcular el valor de las
celdas.
En este caso en concreto se deseaba visualizar el nombre del producto,
como el tabla de pedidos sólo figuraba el código del mismo se añadió una nueva
columna en la cláusula select llamada Producto que se corresponda con el campo
Nombre de la tabla de artículos. Para vincular el código del artículo de la
tabla de pedidos con el nombre del misma de la tabla artículos se insertó la
cláusula INNER JOIN.
La cláusula GROUP BY especifica el
agrupamiento de los registros, contrariamente a los manuales de instrucción esta
cláusula no es opcional ya que debe figurar siempre y debemos agrupar los
registros por el campo del cual extraemos la información. En este caso existen
dos campos del cual extraemos la información: pedidos.cantidad y
artículos.nombre, por ellos agrupamos por los campos.
Para finalizar la cláusula PIVOT indica el
nombre de las columnas no opcionales, en este caso 1996 y 1997 y como vamos al
dato que aparecerá en las columnas, en este caso empleamos el año en que se
produjo el pedido, extrayéndolo del campo pedidos.fecha.
Otras posibilidades de fecha de la cláusula
PIVOT son las siguientes:
- Para agrupamiento por Trimestres
PIVOT "Tri " & DatePart("q",[Fecha]);
- Para agrupamiento por meses (sin tener en cuenta el año)
PIVOT Format([Fecha],"mmm") In ("Ene", "Feb", "Mar", "Abr", "May",
"Jun", "Jul", "Ago", "Sep", "Oct", "Nov", "Dic");
- Para agrupar por días
PIVOT Format([Fecha],"Short Date");