Dibujos SQL
Shlomi Noach es también un Instructor, desarrollador y DBA Certificado de MySQL, que vive en Israel. Le he pedido permiso para traducir al español algunas de sus entradas acerca de maneras creativas de usar SQL que leí a través del Planet MySQL. Éste es el primer post de la serie. Podéis leer la entrada original en inglés en su blog.
SQL no está pensado para generar gráficos, por supuesto, pero veo algunos casos en los que generar salidas no tabulares puede ser útil, tal y como mostraré en futuras entradas.
Me gustaría explicar los fundamentos del funcionamiento de los gráficos SQL: de hecho, es posible hacer todo lo que quieras. ¿Cómo?
Sistema de coordenadas
Desarrollaremos primero un sistema de coordenadas usando SQL. Generando esto, habré probado mi tesis de que cualquier cosa es posible, y proporcionaré además una prueba de concepto.
Para empezar con la generación de coordenadas, necesitaré una tabla de ayuda: una tabla de números (tinyint_asc, por ejemplo, con números entre 0 y 255).
Intentaremos producir una matriz de coordenadas 10×10. Para hacer esto, haremos un join de la popia tabla numérica sobre sí misma (autojoin o self-join) , y utilizaremos una variable para establecer el tamaño de la matriz.
SELECT * FROM tinyint_asc numbers1, tinyint_asc numbers2, (select @size := 10) sel_size WHERE numbers1.value < @size AND numbers2.value < @size ; +-------+-------+-------------+ | value | value | @size := 10 | +-------+-------+-------------+ | 0 | 0 | 10 | | 1 | 0 | 10 | | 2 | 0 | 10 | | 3 | 0 | 10 | | 4 | 0 | 10 | | 5 | 0 | 10 | | 6 | 0 | 10 | | 7 | 0 | 10 | | 8 | 0 | 10 | | 9 | 0 | 10 | | 0 | 1 | 10 | | 1 | 1 | 10 | | 2 | 1 | 10 | | 3 | 1 | 10 | | 4 | 1 | 10 | | 5 | 1 | 10 | | 6 | 1 | 10 | ... | 7 | 8 | 10 | | 8 | 8 | 10 | | 9 | 8 | 10 | | 0 | 9 | 10 | | 1 | 9 | 10 | | 2 | 9 | 10 | | 3 | 9 | 10 | | 4 | 9 | 10 | | 5 | 9 | 10 | | 6 | 9 | 10 | | 7 | 9 | 10 | | 8 | 9 | 10 | | 9 | 9 | 10 | +-------+-------+-------------+
El siguiente paso será presentar las coordenadas de una manera ligeramente distinta (esto es sólo para visualizarlo de manera gráfica):
SELECT CONCAT(numbers2.value, '.', numbers1.value) FROM tinyint_asc numbers1, tinyint_asc numbers2, (select @size := 10) sel_size WHERE numbers1.value < @size AND numbers2.value < @size ; +---------------------------------------------+ | CONCAT(numbers2.value, '.', numbers1.value) | +---------------------------------------------+ | 0.0 | | 0.1 | | 0.2 | | 0.3 | | 0.4 | | 0.5 | | 0.6 | | 0.7 | | 0.8 | | 0.9 | | 1.0 | | 1.1 | | 1.2 | | 1.3 | | 1.4 | | 1.5 | | 1.6 | | 1.7 | ...
Ya es hora de convertir esto en un sistema de coordenadas:
SELECT
GROUP_CONCAT(
CONCAT(numbers2.value, '.', numbers1.value)
ORDER BY numbers1.value
SEPARATOR ' ') AS coordinates
FROM
tinyint_asc numbers1,
tinyint_asc numbers2,
(select @size := 10) sel_size
WHERE
numbers1.value < @size
AND numbers2.value < @size
GROUP BY numbers2.value
;
+-----------------------------------------+
| coordinates |
+-----------------------------------------+
| 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 |
| 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 |
| 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 |
| 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 |
| 4.0 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 |
| 5.0 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 |
| 6.0 6.1 6.2 6.3 6.4 6.5 6.6 6.7 6.8 6.9 |
| 7.0 7.1 7.2 7.3 7.4 7.5 7.6 7.7 7.8 7.9 |
| 8.0 8.1 8.2 8.3 8.4 8.5 8.6 8.7 8.8 8.9 |
| 9.0 9.1 9.2 9.3 9.4 9.5 9.6 9.7 9.8 9.9 |
+-----------------------------------------+
Esto es todo lo que necesitamos para generar cualquier gráfico que queramos. Usa tu función matemática favorita, aplica la geometría analítica y haz que suceda. En vez de mostrar las coordenadas, úsalas para decidir lo que debería ser mostrado.
Prueba de concepto
Para demostrar que la frase anterior es realmente sencilla, mostraré cómo dibujar un círculo usando las coordendas SQL. La famosa fórmula del círculo es:
(x-x0)² + (y-y0)² = rad²
siendo x0, y0 las coordendas del centro del círculo y rad, el radio.
Para aplicarla:
SELECT
GROUP_CONCAT(
IF(
ROUND(SQRT(POW(numbers1.value-(@size-1)/2, 2) + POW(numbers2.value-(@size-1)/2, 2))) <= @radius,
'#', '-')
ORDER BY numbers1.value
SEPARATOR ' ') AS circle
FROM
tinyint_asc numbers1,
tinyint_asc numbers2,
(select @size := 15) sel_size,
(select @radius := 6) sel_radius
WHERE
numbers1.value < @size
AND numbers2.value < @size
GROUP BY numbers2.value
;
+-------------------------------+
| circle |
+-------------------------------+
| - - - - - - - - - - - - - - - |
| - - - - - # # # # # - - - - - |
| - - - # # # # # # # # # - - - |
| - - # # # # # # # # # # # - - |
| - - # # # # # # # # # # # - - |
| - # # # # # # # # # # # # # - |
| - # # # # # # # # # # # # # - |
| - # # # # # # # # # # # # # - |
| - # # # # # # # # # # # # # - |
| - # # # # # # # # # # # # # - |
| - - # # # # # # # # # # # - - |
| - - # # # # # # # # # # # - - |
| - - - # # # # # # # # # - - - |
| - - - - - # # # # # - - - - - |
| - - - - - - - - - - - - - - - |
+-------------------------------+
¡Elimina el espacio separador, juega con el ratio, aplica tu propia fórmula y genera dibujos SQL-ascii!






agosto 17th, 2009 at 06:26
BUENISSSSSSSIMOOOOOO!!!!!!!!!!!!
Me alegra saber que hay gente tan inteli gente y de la cual podemos aprender,eso muy extraño en este mundo donde impera la violencia….en todos los “tiempos” grama ticales…..
Lunareja de montevideo……….
Uruguayyyyyy!!!!!!