Ir al contenido principal

Puzzles en T-SQL ¿te atreves a encontrar la respuesta?

Recientemente, Pinal Dave publicó en su blog SQL Authority un post con dos puzzles para Transact SQL. La curiosidad nos hizo intentar averiguar las respuestas, y aquí va lo que descubrimos (podéis intentar adivinarlas antes de leer la solución):



Puzzle 1. ¿Por qué la siguiente query produce como resultado un asterisco (*)?
SELECT CAST (100 AS varchar(2))
Podríamos esperar un error de desbordamiento, que el 100 se truncara por alguna de sus extramos y quedase reducido a un 10 o a un doble cero (00). Pero no, SQL Server nos retorna un asterisco.

Solución: La MSDN nos explica cómo actúa el motor de la base de datos a la hora de convertir un número (smallint, int...) a una cadena. Si la cadena soporta caracteres Unicode (nchar o nvarchar), se producirá un error. Sin embargo, si estamos intentando convertir el número en un char o varchar con menor longitud de la necesaria, obtendremos un asterisco. Dicho asterisco -nos explica el artículo- quiere decir que la longitud resultante es demasiado corta para mostrar el valor.

Conversiones de números en cadenas de tamaño insuficiente, según la MSDN
Puzzle 2. ¿Cuál es la sentencia más corta que produce un 1 como resultado, sin usar números?

Para esta pregunta encontramos una discusión abierta en el grupo SQL Server Developers de LinkedIn. Allí, el ingenio de algunos de los participantes nos llevó a respuestas cada vez más cortas. Os intentamos explicar cada una de ellas.

Solución: Inicialmente nos encontramos con la siguiente query:
SELECT COUNT(*)
COUNT(*) nos devuelve el recuento del número de filas afectadas por la sentencia SELECT. Como no estamos devolviendo filas de una tabla, SQL asume que el número de filas devueltas es uno (como si ejecutásemos una SELECT de una lista de valores constantes - SELECT constante1, N'constante2', dia-mes-año...)

Con la misma longitud existe otra solución: Pedirle a SQL Server la longitud de una cadena de texto de un solo carácter. Así:
SELECT LEN('a')
Buenos intentos, pero se pueden mejorar. SQL Server acepta los tipos de datos money y smallmoney. Para representar estos tipos de datos, se pueden usar símbolos de moneda. Así, 100€ se pueden representar como €100. Si dejamos la parte numérica vacía, SQL Server interpreta que la cantidad es cero. Así, SELECT $ nos devolvería 0.00.

A partir de un cero, ¿qué funciones SQL nos pueden devolver un uno? Son las siguientes:


SELECT EXP($) -- El número e elevado a cero es uno.
SELECT DAY($) -- El día cero para SQL Server es el 1 de enero de 1900, así que cogemos el día
SELECT COS($) -- El coseno de 0 es 1.


¿Podéis mejorarlo? :)

Comentarios

Publicar un comentario

Entradas populares de este blog

Aprendiendo a usar LEFT OUTER JOIN

En esta entrada pretendemos explicar los diferentes resultados obtenidos por distintas construcciones de consultas que, aparentemente, deberían producir el mismo conjunto de resultados. Así, veremos las diferencias entre filtrar los resultados de una query en la unión (Join) mediante condiciones ON y mediante cláusulas WHERE.

Variantes del SELECT COUNT con DISTINCT

Seguramente, muchos de vosotros habréis usado en innumerables ocasiones la función de T-SQL COUNT , que no hace sino devolver un número de registros: de una tabla, de un conjunto de resultados, etc... En una de sus aplicaciones, combinado con el DISTINCT -uno de los dos argumentos que admite- COUNT nos devuelve el número de valores únicos no nulos de la tabla o conjunto de resultados que estemos consultando. Pero ¡ojo! Cuidado con la sintaxis , o podemos obtener el valor equivocado sin darnos cuenta. No es lo mismo: SELECT COUNT (DISTINCT NombreCampo) FROM NombreTabla que: SELECT COUNT(*), DISTINCT NombreCampo FROM NombreTabla

Script para obtener el tamaño de todas las tablas de la base de datos

En algunas ocasiones podemos vernos con la necesidad de conocer qué tablas de nuestra base de datos están ocupando más espacio en disco. Por ejemplo, si disponemos de SQL Server Express , cuyas bases de datos están limitadas a 4GB o 10GB, según la versión que estemos usando -4, hasta 2005; 10, a partir de 2008-, aparte de usar las opciones de comprimir la base de datos, poner el log en el modo simple de recuperación o ajustar las políticas de crecimiento automático de nuestros ficheros, podemos necesitar averiguar qué tablas crecen más para tomar las decisiones oportunas.