viernes, 22 de febrero de 2013

SQL para Access: filtrado y ordenación de datos

                    (P) Hugo Napoli, 2013                    


Filtrado y ordenación de datos con el motor SQL incorporado en Access.

Con Access podemos, tal como se ha visto en el anterior post sobre bases de datos, generar un espacio de trabajo en donde la información se mantenga dentro de un marco fidedigno y libre de distorsiones perjudiciales.
Se puede evitar que los datos se dupliquen, por ejemplo.
Se puede controlar el ingreso de datos, para que todos quienes utilicen las tablas para introducir información, lo hagan de una sola manera y siguiendo patrones que eviten mediocrizar la calidad de las estructuras de datos.

Pues bien, para que podamos redondear nuestro trabajo, es necesario obtener datos filtrados de la base, no solamente volcárselos sistemáticamente a modo de colección logarítmica.
Debemos poder filtrar y ordenar los datos; presentarlos en pantalla o en impresora según un criterio surgido de las necesidades originadas por una determinada situación laboral, por ejemplo.

Para una base de datos de gran cantidad de registros, existen muchos filtrados posibles:
- las personas que vivan en un barrio determinado,
- los individuos que sean mayores de edad,
- los que posean casilla de correo de gmail,
- etc.
Una manera de obtener este tipo de datos, es -en lugar de imprimirlos todos y tachar los que no correspondan, o bien copiarlos a una planilla de Excel y eliminar lo que nos resulte inútil- la utilización del lenguaje SQL, y Access posee un motor SQL para este tipo de operaciones.

SQL deriva de las siglas "Structured Query Language", o bien "Lenguaje de consulta estructurado", y sirve tanto para crear bases de datos, tablas, campos, registros y relaciones entre campos, como para modificar, agregar y eliminar todo tipo de datos, y para consultar a la base.

Esto último es lo que veremos en este momento, puesto que todo lo anterior puede hacerse con Access sin mayores problemas.

Para efectuar una consulta en lenguaje SQL, debemos tener al menos una base de datos con una tabla, que a su vez contenga algún que otro registro completo.

Una vez sorteada esta situación, procederemos a abrir la base de datos.


PASO 1: creación de la consulta.

A continuación abriremos la tabla y seleccionaremos, en el menú "Crear", la opción "Diseño de consulta".


Con esto se abrirá el asistente de selección de tablas.

PASO 2: selección de la tabla propicia.

Marcaremos la tabla que contiene los datos que deseamos ordenar y/o filtrar, pulsaremos "Agregar" y luego "Cerrar".
Si lo hemos hecho bien, la tabla quedará agregada en el espacio de consulta correspondiente, generándose una pestaña para dicho propósito, al igual que cuando se crea una relación o una tabla.
En la imagen que sigue se ve cómo se ha agregado al espacio de consulta a la tabla "Datos".


PASO 3: cambio a vista SQL.

Luego de cerrar el asistente, debemos cambiar a vista SQL.
Para ello utilizaremos el menú "Ver" y su opción correspondiente: "Vista SQL".


Ya estamos preparados para introducir el código SQL de nuestra consulta.
Debemos, antes que nada, borrar todo lo que esté escrito en el editor SQL.
Access genera, por defecto, las líneas siguientes:

SELECT
FROM Datos;


lo cual generará errores si guardamos la consulta y pretendemos ejecutarla... Hay que decirlo otra vez: ¡¡¡así es Access!!!!

PASO 4: escritura de la sentencia SQL.

El editor SQL es una especie de "bloc de notas" que responde a un motor SQL incluido en Access.
Todo lo que escribamos en él será interpretado por el motor SQL al ser ejecutada la consulta.


SELECCIONAR LOS DATOS

En este caso, solamente hablaremos de consultas de petición (o selección) de datos.
Utilizaremos al motor SQL que acompaña a Access para consultar a la base de datos, y filtrar a su vez la información.

La estructura de las consultas de petición comienza siempre así:

SELECT [nombre de los campos que queremos filtrar o visualizar]
FROM [nombre de la tabla que contiene los datos]

Un ejemplo sería el siguiente:

SELECT Nombre, Apellido, Dirección
FROM Clientes


Cuando el motor SQL encuentra a la instrucción SELECT al comienzo de una sentencia, interpreta que dicha consulta es de petición o selección de datos. Con FROM, al motor SQL se le indica el lugar desde donde levantar o extraer los datos (la tabla en donde se hallan los registros que nos interesan).


Al ejecutar la consulta de arriba, lo que sucedería sería lo siguiente:
veríamos solamente los nombres, los apellidos y las direcciones de los registros de la tabla CLIENTES.

Como se ve, si necesitamos un solo campo, escribiremos SELECT [nombre de campo], pero si los campos a visualizar son varios, los separaremos por comas utilizando sus nombres, escritos exactamente como figuran en la tabla correspondiente: SELECT Campo1, Campo2, Campo3

Si necesitáramos visualizar todos los campos existentes de la tabla, utilizaríamos un asterisco como sustituto de los nombres de los campos, es decir que con una sentencia como la que sigue

SELECT *
FROM Clientes

el motor SQL presentaría todos los campos existentes como resultado de la operación.

Pues bien: ¿qué sentido tiene el hecho de visualizar en una consulta los mismos campos que podemos ver simplemente abriendo la tabla correspondiente y observando su contenido?
La respuesta es... ¿ninguno?

Bien.
De todos modos, una sentencia SQL de petición de datos siempre comienza así, como se ha visto más arriba.
Luego, los datos pueden filtrarse y ordenarse, para que al leerlos, analizarlos o interpretarlos, el trabajo resulte más sencillo y amigable que leer una lista de 786 hojas de papel de fanfold continuo impresas por una impresora de matriz de puntos...


ORDENAR LA INFORMACIÓN

Existe la sentencia ORDER BY, con la cual podemos pedir al motor SQL que ordene los datos antes de presentarlos en pantalla.
Si quisiéramos presentar los datos en ordena alfabético de la A a la Z, por ejemplo, sólo necesitamos introducir las líneas descritas arriba, seguidas por un ORDER BY [campo de referencia]:

SELECT *
FROM Clientes
ORDER BY Apellido

Esto presentaría todos los datos (debido a la existencia de un asterisco en la sentencia) de la tabla Clientes, ordenados por apellido, de la A a la Z.
Si quisiéramos ordenar los datos por nombre del cliente en lugar de hacerlo por apellido, escribiríamos:

SELECT *
FROM Clientes
ORDER BY Nombre

NOTA IMPORTANTE: el comando ORDER BY, siempre debe ser colocado al final de la sentencia SQL.

FILTRAR LA INFORMACIÓN

Para el filtrado existe WHERE, la palabra clave que le indica al motor SQL que deberá cumplirse una condición determinada para que la consulta tenga efecto. Para quien recuerde el funcionamiento de la función SI de Excel, diremos que esto funciona de modo muy similar a como sucede en dicha función.
WHERE siempre va colocado antes que ORDER BY. Observemos la siguiente estructura:

SELECT [campo/s]
FROM [tabla]
WHERE [condición]
ORDER BY [campo]

Un ejemplo podría ser el siguiente:

SELECT *
FROM Clientes
WHERE Edad = 25
ORDER BY Apellido

Esta consulta mostraría todos los registros de la tabla Clientes, siempre y cuando en el campo edad de cada uno se halle la cifra 25, y lo ordenaría alfabéticamente.

La sentencia WHERE, admite los operadores lógicos AND (y) y OR (o), < (menor), <= (menor o igual), > (mayor), >= (mayor o igual), = (igual), <> (diferente), y otros...

SELECT *
FROM Clientes
WHERE Edad <> 25
ORDER BY Apellido

Existe también el comando NOT, que sirve para negar.
Del mismo modo que le decimos al motor SQL "los diferentes a 25" (Edad <> 25), también podríamos decirle "los que NO sean de 25" (WHERE NOT Edad = 25):


SELECT *
FROM Clientes
WHERE NOT Edad = 25
ORDER BY Apellido


El ejemplo anterior, y este último, hacen exactamente lo mismo: mostrar todos los clientes que NO TENGAN 25 años, ordenados por apellido.

SELECT *
FROM Clientes
WHERE Edad > 25
ORDER BY Apellido

Muestra los clientes mayores de 25 años, ordenados por apellido.

Pero no solamente pueden filtrarse datos en función de una cuestión numérica.
Puede trabajarse también con texto, es decir, con datos alfanuméricos.
Si quisiéramos, en lugar de trabajar con edades, hacerlo con zonas, podríamos hacer lo siguiente:

SELECT *
FROM Clientes
WHERE Zona = Norte
ORDER BY Apellido


Esta sentencia, si bien en lo imaginario se corresponde con el sentido común y en apariencia debería funcionar a la perfección, encierra un par de errores de sintaxis.

Dichos errores se han resaltado con color rojo, y su corrección será explicada a continuación.


1. Cuando trabajemos con cadenas de texto (palabras, valores alfanuméricos, etc.) es conveniente  utilizar el comando LIKE en lugar del signo de igual. Si bien de las dos maneras se obtiene el mismo resultado, a la larga uno se organiza mejor si utiliza un procedimiento diferente al trabajar con cadenas de texto o datos alfanuméricos. En el ejemplo de arriba se ha visualizado la sentencia SQL utilizando el signo de igual, y en el siguiente se puede ver la misma sentencia, utilizando el operador LIKE.

SELECT *
FROM Clientes
WHERE Zona LIKE Norte
ORDER BY Apellido

2. Si queremos que el motor SQL realice comparaciones entre cadenas de texto, encerrémoslas entre comillas:

SELECT *
FROM Clientes
WHERE Zona LIKE "Norte" [esta línea puede sustiruirse por WHERE Zona = "Norte"]
ORDER BY Apellido


DOBLE FILTRADO: BÚSQUEDA DE PALABRAS



Es posible que tengamos que buscar o extraer ciertos datos antes de realizar el filtrado.
Por ejemplo, ¿qué sucedería si queremos obtener únicamente los números telefónicos de un determinado barrio?
Para filtrar los números telefónicos del Centro de Montevideo, deberíamos poder presentar en pantalla todos aquéllos que comiencen con 290, por ejemplo, sin importar el resto de los números que compongan la cadena total.
Esto es posible gracias a un artilugio que le dice al motor SQL que no se fije en ciertos caracteres al realizar el filtrado.
¿Cómo funciona esto?
Utilizando el asterisco en el lugar o los lugares que queremos despreciar.
Observemos los siguientes números telefónicos y visualicemos cuáles son las únicas cifras que los hacen pertenecer a la misma zona.

29017575
29014646
29005858
29021717
29002121
29024343


Dado que la característica zonal es la misma en todos (290) y que por lo tanto podríamos despreciar al resto de las cifras que siguen al 290, sustituiremos a todas esas cifras por un sólo asterisco, de este modo: 290*

¿Y cómo se logra transmitirle eso mismo al motor SQL?
Del mismo modo que en los últimos ejemplos de código SQL:


SELECT *
FROM Clientes
WHERE Teléfono LIKE "290*"

En este caso, el motor mirará únicamente si las cifras comienzan con 290 y despreciará el resto, por lo tanto, la consulta SQL desplegará todos los números que ya hemos citado anteriormente:


29017575
29014646
29005858
29021717
29002121
29024343

¿Y si necesitamos saber qué teléfonos terminan con 5?
Podemos cambiar al asterisco de lugar:


SELECT *
FROM Clientes
WHERE Teléfono LIKE "*5"



Esto significa que el motor despreciará toda cifra que haya antes del 5, y sólo observará al 5 como cifra final, devolviendo únicamente este número:

29017575

¿Y si la cadena de texto buscada está en el medio de la palabra, como por ejemplo, buscar "mar" dentro de "Amaral"?
Pues bien; si la cadena de texto buscada está justo en medio de la palabra, o bien si se desconoce exactamente en qué posición dentro del texto se hallará, se pueden utilizar dos asteriscos:
Para el ejemplo de búsqueda de la cadena de texto "mar" dentro de la palabra "Amaral", el planteamiento SQL se haría de la siguiente manera:


SELECT *
FROM Clientes
WHERE Nombre LIKE "*mar*"

Este ejemplo devolverá todos los nombres que contengan la palabra "mar" dentro de sí, y será válido tanto como para los que comienzan con "mar", como "Marcela", para los que contienen "mar" en medio de la palabra, como "Amaral", como para los que culminan con "mar", como "Omar".


Del mismo modo pueden extraerse todos los clientes que posean direcciones de correo del servidor gmail,


SELECT *
FROM Clientes
WHERE Correo LIKE "*gmail*"

los de yahoo,

SELECT *
FROM Clientes
WHERE Correo LIKE "*yahoo*"


los de hotmail,


SELECT *
FROM Clientes
WHERE Correo LIKE "*hotmail*"

etc.


En el post sobre Access está disponible la descarga de una base de datos en donde podrás encontrar todas estas consultas SQL ya resueltas.

Espero que la información te haya sido útil.

Gran abrazo.