PostgreSQL: Consulta para saber en qué tabla está una columna

Lo hicimos en Oracle, en SQL-Server y en MySQL. No podíamos dejarnos PostgreSQL ¿cómo podemos saber en qué tabla está una columna sabiendo sólo el nombre de dicha columna?

Pues con una consulta sobre la vista columns, que contiene información sobre las columnas de todas las tablas y vistas. Veamos cómo sabríamos en qué tabla está la columna “NombrePaciente” (por poner un ejemplo práctico):

Select table_name
from columns
where column_name like 'NombrePaciente'

En vuestro caso cambiáis NombrePaciente por el nombre de columna que corresponda.

MySQL y MariaDB: Consulta para saber en qué tabla está una columna

El otro día lo vimos en SQL-Server, ayer en Oracle, vamos hoy con MySQL y su fork MariaDB, seguramente los gestores de bases de datos SQL libres más populares de la actualidad ¿Cómo puedo saber a qué tabla pertenece una columna sabiendo sólo el nombre de columna? Como en los casos anteriores, basta una consulta:

SELECT DISTINCT TABLE_NAME
    FROM INFORMATION_SCHEMA.COLUMNS
    WHERE COLUMN_NAME = 'Nombre_Columna'
        AND TABLE_SCHEMA='Nombre_BaseDatos';

Ya sabéis, os toca cambiar el nombre de columna y el nombre del esquema por los que correspondan en vuestro caso.

Oracle: Consulta para saber en qué tabla está una columna

Ayer veíamos cómo hacer esto en SQL-Server, cómo saber a qué tabla pertenece una columna a partir del nombre de esta. ¿Cómo se hace en Oracle? Pues tenemos también una consulta que nos lo dice, pero distinta:

select table_name from all_tab_columns where column_name='Nuestra_columna';

Cambiando el ‘Nuestra_Columna‘ por el término en cuestión.

SQL-Server: Consulta para saber en qué tabla está una columna

Vamos con un tip rápido de SQL-Server, y seguramente útil en muchas ocasiones. Me acaba de pasar que ejecutaba un script para pasar datos de una base de datos vieja a una nueva (donde las tablas tienen algunas diferencias, al ser un versión posterior de la aplicación) y me devolvía como error que el tipo de datos no era válido para la columna Envases. Y me asalta la duda y la necesidad ¿en qué tabla está esa columna? Pues podemos saberlo con una consulta:

SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME = 'Envases'
ORDER BY DATA_TYPE

En vuestro caso debéis cambiar Envases por el nombre de columna que corresponda. Próximamente lo veremos en Oracle.

MySQL: Calcular una edad a partir de una fecha.

En fin, seguimos con el cálculo de edades a partir de fechas en diferentes SGBD. Ya hablamos de SQL-Server y de PostgreSQL, vamos ahora a ver cómo iría la cosa en MySQL/MariaDB.

Vamos a asumir que los datos están bien guardados, en una columna del tipo DATETIME. Como en el caso de Postgres, en MySQL dispones de una función que nos ayudará a hacer esto directamente, llamada TIMESTAMPDIFF(). Esta función recibe como argumentos la unidad de tiempo en la que queremos recibir la respuesta y las dos fechas entre las que queremos obtener la diferencia. Veamos el ejemplo para obtener la edad de alguien con esta función, sirviéndonos de una tabla de ejemplo llamada clientes que contendrá una columna FechaNac con la fecha de nacimiento de los mismos:

SELECT TIMESTAMPDIFF(YEAR,FechaNac,CURDATE()) AS edad
     FROM clientes;

PostgeSQL: Calcular una edad a partir de una fecha.

No hace mucho veíamos cómo calcular una edad en SQL-Server. Vamos ahora con otro SGBD ¿Cómo lo hago en Postgres? Pues con mucha menos dificultad, porque este gestor incluye ya una función integrada para el cálculo de edades, presente al menos desde la versión 9 (no se si antes) llamada age().

La función puede ser llamada con uno o con dos argumentos, siempre del tipo timestamp, y devuelve el interváluo entre ambos. Para el ejemplo imaginemos una tabla llamada clientes donde tenemos un campo FechaNac con la fecha de nacimiento guardada.

/*Con el primer ejemplo
pasando sólo una fecha
cogería la edad a día de hoy
de alguien nacido en esa fecha*/
Select age(timestamp FechaNac) from clientes

/*Con el segundo ejemplo
pasando dos fechas
cogería la edad que una
persona nacida en la fecha 2
tenía en la fecha 1*/

Select age(timestamp '2014-01-01',timestamp FechaNac) from clientes

SQL Server: Calcular una edad a partir de una fecha.

¿Cuántas veces no tenemos que sacar, en una consulta, la edad de una persona a partir de su fecha de nacimiento? Es una consulta que me toca hacer habitualmente (y que, mira por dónde, nunca había comentado aquí). ¿Cómo lo hacemos en SQL-Server?

Pensemos que tenemos una tabla clientes, donde hay un campo de tipo DATE llamado FechaNac en el que almacenamos sus fechas de nacimiento. Podrías creer que lo más simple es hacer lo siguiente:

Select DATEDIFF(YEAR,FechaNac,GETDATE()) as Edad from clientes

Pero hay un problema: Esa solución sólo resta los años, no tiene en cuenta el mes y el día ¿qué pasaría entonces? Que nos pondría la edad que ese cliente va a cumplir durante este año, no su edad real. ¿Cómo lo solucionamos? Hay muchas opciones, yo he optado por esta:

Select DATEDIFF(YEAR,FechaNac,GETDATE())
-(CASE
   WHEN DATEADD(YY,DATEDIFF(YEAR,clientes.FechaNac,GETDATE()),clientesFechaNac)>GETDATE() THEN 
      1
   ELSE 
      0 
   END) as Edad
 from clientes

Lo que hacemos es sumar la diferencia de años a la fecha de nacimiento y, en caso de que fuera posterior a hoy (es decir, todavía no ha cumpliado años) restamos 1 a la diferencia, si no restamos 0 y nos quedamos como estamos.

Otra opción, más elegante, podría ser esta:

Select floor(
(cast(convert(varchar(8),getdate(),112) as int)-
cast(convert(varchar(8),clientes.FechaNac,112) as int) ) / 10000
) as edad from clientes

En este caso convertimos la fecha al formato clásico de base de datos como una cadena que aglutina pegados Fecha, mes y día y lo convertimos a un entero (hoy nos quedaría por ejemplo 20151001), se lo restamos a la fecha de nacimiento, dividimos entre diez mil para obtener el año y redondeamos por defecto con la función floor().

Borrar un evento de MySQL

Hoy me preguntaba en la entrada sobre Eventos en MySQL cómo se borran, así que en vez de contestar en los comentarios voy a dejarlo por aquí en una minientrada general. ¿Cómo se borra un evento? Pues con Drop Event, cuya sintaxis es DROP EVENT [IF EXISTS] event_name. En el viejo ejemplo creábamos uno llamado e_ActualizaSaldoDiario, así que si quisiéramos borrarlo nos bastaría con hacer lo siguiente:

DROP EVENT e_ActualizaSaldoDiario

En caso de que el evento que intentamos borrar no existiera (por haberse borrado previamente) nos devolverá un error. Si queremos evitar esto podemos añadir IF EXISTS:

DROP EVENT IF EXISTS e_ActualizaSaldoDiario

Recordad que para borrarlos, igual que para crearlos, tenéis que tener permisos sobre los eventos en el schema.

SQL-Server ¿es mejor usar MAX() o TOP 1?

Una duda me asaltaba el otro día preparando una serie de consultas, en una de las cuales tenía que sacar la fecha más alta de una serie de registros. ¿Consumía menos recursos un MAX() o acaso era mejor recurrir a la conjunción de order by y Top 1?

Rebuscando por duckduckgo me encontré con este blog donde disipan la duda:

  1. Si el campo a buscar forma parte de un índice cluster, entonces da igual porque ambas se ejecutan a una velocidad extremadamente rápida
  2. Si el campo a buscar no es un índice cluster entonces MAX() da una respuesta más rápida porque la función está mejor optimizada y tiene menos carga que realizar un order by después del select

En el artículo original están los bancos de pruebas con resultados concretos.

Diferencias entre clave primaria y clave foránea

Vamos con una entrada de SQL básico, uno de los fundamentos del modelo relacional ¿Qué diferencia existe entre una clave primaria y una foránea?

En el diseño de una base de datos relacional la clave primaria es el campo, o conjunto de campos, que nos permite identificar de forma única un registro. Por así decirlo es como el DNI de esa tabla. Se trata de un valor, o grupo de valores, único que nos permitirá diferenciar un registro concreto. Podemos definir la clave primaria en el momento de la creación de la tabla, dentro de la sintaxis del CREATE TABLE, o a posteriori añadiendo la regla en un ALTER TABLE.

Por su parte la clave foránea es un campo, o conjunto de campos, que nos permite relacionar un registro de una tabla con otro, generalmente de una tabla distnta . Como ejemplo piensa en la clásica base de datos de una tienda, en la que tienes una tabla con productos, cada uno de los cuales tiene un código (que será la clave primaria), una descripción y un precio. Por otra parte tienes una tabla en la que registras las ventas, y podrías tener un código para cada una, la fecha, la hora y el producto. Para identificar el producto en esa tabla lo más práctico, para no repetir información, sería utilizar el código de la tabla de productos (la clave primaria de la primera tabla, que en esta se convierte en clave externa).

Una tabla puede tener relaciones con varias a través de distintas claves foráneas, e incluso referenciarse a si misma (clave foránea recursiva). Al igual que con la clave primaria podemos definir las claves foráneas dentro de la sintaxis de creación de la tabla o a posteriori con un ALTER TABLE.

Por tanto la diferencia es sencilla: la clave primaria identifica un registro único de una tabla. La clave foránea relaciona los datos de un registro de una tabla con los de otra, o con un registro distinto de la misma tabla.