jueves, 17 de marzo de 2011

INSERTAR DATOS DESDE UN SELECT CON POSTGRESQL

Me tope con un problema en una base de datos postgresql, el cual era insertar datos en una tabla pero dichos datos provienen de una consulta de otra tabla.

Esto se podría haber hecho con un script de ruby o en la consola, pero encontré probando y buscando, una solución desde la terminal pgsql.

La sintaxis es la siguiente:

INSERT INTO table (field1,field2,field3) SELECT id,other_value FROM table WHERE conditions...

Expliquemos un poco esto:

La primera parte es el típico INSERT de SQL, la sintaxis general cambia un poco pero en escencia es lo mismo.

INSERT INTO table -> table es el nombre de la tabla en la cual queremos insertar los datos resultado de una consulta.

despues del nombre de la tabla se colocan los campos en que deseamos caigan los datos producto de la consulta, por ej. si en la tabla destino tenemos tres campos, id, nombre, apellido, y queremos solo insertar nombre tendriamos una estructura similiar a: INSERT INTO tabla (nombre)... vease que el nombre del campo va entre parentesis y se pueden colocar varios campos seguidos por comas, por ej. (nombre,apellido,edad...etc..)... hasta aqui no hay nada nuevo en un INSERT normal de SQL.

Despues de esto viene lo interesante, omitimos la clausa VALUES que normalmente usamos para insertar un registro e inmediatamente colocamos nuestra consulta, osease, el SELECT..

Esta parte es importante analizar, ya que si colocamos un SELECT * FROM tabla; obtendremos todos los valores de esa tabla por lo que en la parte donde colocamos el nombre de los campos que deseamos llenar osea el

INSERT INTO table (field1,field2,field3)

debe conincidir con el numero de campos que estamos obteniendo del select, no es lo mismo el numero de campos que el numero de registros, osease el numero de cmapos es el numero de columnas que esperamos recibir no de filas o registros.

Practicamente con esto estariamos insertando todos los registros que devuelva la consulta en los campos que seleccionamos en el INSERT.

Que mas podemos hacer...??

En la parte del SELECT podemos colocar condiciones normales con la clausula WHERE como solemos usarla por ej. SELECT * FROM patients WHERE id = 10;

Otra cosa que podemos hacer dentro de la clausula SELECT es indicarle los campos que desamos inserte, por ejemplo, solo desamos insertar algunos campos del resultado de una consulta de la sig FORMA.

INSERT into clientes (nombre,apellido) SELECT nombre,apellido FROM provedores WHERE country_id = 30:

Aqui estamos insertando solo los valores de dos columnas (nombre y apellido) pero a su vez estamos insertando todos los nombres y apellidos que tengan country_id = 30.

Algo más...??

En caso que deseemos insertar tanto valores resultado de una consulta como algun valor fijo que querramos, podemos colocarlo despues del a seleccion de campos, de le sig forma

INSERT into clientes (nombre,apellido,status) SELECT nombre,apellido,"comprado" FROM provedores WHERE country_id = 30:

aqui el valor "comprado" no es un valor que se obtiene del select, es mas bien un valor arbitrario que se estara insertando indicriminadamente con el valor que yo decida colocar, otra forma de hacerlo para que se vea mas claro es la siguiente:


INSERT into clientes (nombre,apellido,status) SELECT (nombre,apellido),"comprado" FROM provedores WHERE country_id = 30:

La palabra en comillas "comprado" fuera del parentesis es una constante, osease un valor que no se obtiene de la consulta y que mas bien nosotros queremos que se inserte en conjunto con lo que obtenemos pero en otro campo.


Aqui un ejemplo de como se usa en general todo esto:


INSERT INTO rols (dependency_id,job_id) SELECT (id),68 from dependencies where category_id = 3;


Y de esta forma facilmente actualizamos o insertamos datos producto de una consulta.

8 comentarios:

Fabio Ferreira dijo...

Excelente información, muy útil para casos especiales.

Jose dijo...

Un articulo muy bueno, me sirvió de mucho pero planto un problema por si alguien lo sabe:

¿Que ocurre cuando necesitas dos selects dentro del insert en lugar de una?

insert into paciente select "Jose",valor_recuperado_de_una_select,valor_recuperado_de_otra_select_distinta

Gracias!

Lovelace Lady dijo...

Gracias! este artículo me ha servido mucho, muy bien explicado. Saludos desde Guatemala.

Vanicer dijo...

hey muchas gracias....me ayudo al 100%

Administrador del blog dijo...

Gracias bro.

Administrador del blog dijo...

Gracias bro

Tu evento Cristiano dijo...

Justo lo que estaba buscando, gracias por la información. En el select se puede agregar un Left Join?

Nino Delgado dijo...

Magnífico!!! La explicación, detallada y precisa, resulta de una ayuda inconmensurable. Gracias !!!