Pregunta

Tengo una consulta grande en una base de datos PostgreSQL. La consulta es algo como esto:

SELECT * FROM table1, table2, ... WHERE table1.id = table2.id...

Cuando ejecuto esta consulta como una consulta de SQL, esta devuelve la fila deseada.

Pero cuando intento usar la misma consulta para crear una vista, devuelve un error:

" error: columna " id " especificado más de una vez. "

(uso pgAdminIII al ejecutar las consultas)

Supondré que esto sucede porque el conjunto de resultados tendrá más de una columna denominada " id " ¿Hay alguna forma de resolver esto, sin escribir todos los nombres de columna en la consulta?

¿Fue útil?

Solución

Esto sucede porque una vista tendría dos columnas con nombre de identificación, una de la tabla 1 y la otra de la tabla 2, debido a la selección *.

Debe especificar qué ID desea en la vista.

SELECT table1.id, column2, column3, ... FROM table1, table2 
WHERE table1.id = table2.id

La consulta funciona porque puede tener columnas con el mismo nombre ...

postgres=# select 1 as a, 2 as a;
 a | a
---+---
 1 | 2
(1 row)

postgres=# create view foobar as select 1 as a, 2 as a;
ERROR:  column "a" duplicated
postgres=# create view foobar as select 1 as a, 2 as b;
CREATE VIEW

Otros consejos

Si solo las columnas de unión están duplicadas (es decir, tienen los mismos nombres), entonces puedes cambiarte:

select *
from a, b
where a.id = b.id

a:

select *
from a join b using (id)

Si llegó aquí porque está tratando de usar una función como to_date y obtiene la " definida más de una vez " error, tenga en cuenta que necesita usar un alias de columna para las funciones, por ejemplo:

to_date(o.publication_date, 'DD/MM/YYYY') AS publication_date

No hay una forma integrada en el lenguaje para resolverlo (y, francamente, * es una mala práctica en general porque puede provocar defectos latentes a medida que cambian los esquemas de la tabla; puede hacer table1. *, table2.acolumn, Tabl2.bcolumn si desea tener todas las tablas y de forma selectiva de otras), pero si PostgreSQL admite INFORMATION_SCHEMA, puede hacer algo como:

DECLARE @sql AS varchar

SELECT @sql = COALESCE(@sql + ', ', '') 
    + '[' + TABLE_NAME + '].[' + COLUMN_NAME + ']'
    + CHAR(13) + CHAR(10)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME IN ('table1', 'table2')
ORDER BY TABLE_NAME, ORDINAL_POSITION

PRINT @sql

Y pegue los resultados para ahorrar mucho al escribir. Necesitará alias manualmente las columnas que tienen el mismo nombre, por supuesto. También puedes codificar nombres únicos si lo deseas (pero yo no):

SELECT @sql = COALESCE(@sql + ', ', '') 
    + '[' + TABLE_NAME + '].[' + COLUMN_NAME + '] '
    + 'AS [' + TABLE_NAME + '_' + COLUMN_NAME + ']'
    + CHAR(13) + CHAR(10)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME IN ('table1', 'table2')
ORDER BY TABLE_NAME, ORDINAL_POSITION
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top