La tarea es "Encontrar la identificación de la universidad donde el número de empleados graduados de esa universidad es máximo en todas las universidades"
los esquemas son asi
Graduate ( EmpId: NUMERIC REFERENCES Employee(EmpId), UnivId: NUMERIC REFERENCES University(UnivId), GradYear: NUMERIC) University ( UnivId: NUMERIC, UnivName: VARCHAR(40)) Employee (EmpId: NUMERIC, EmpName: VARCHAR(40))mi consulta:
SELECT Temp.UnivId FROM (SELECT G.UnivId, COUNT(*) as Num FROM Graduate G, Employee E WHERE G.EmpId = E.EmpId GROUP BY G.UnivId) AS Temp WHERE Temp.Num = (SELECT MAX(Temp.Num) FROM Temp);Cuando ejecuto esta consulta en la consola psql y el software es PostgresSQL, devuelve un error que dice que la relación "temp" no existe y señala la temperatura al final. ¿Alguien sabe por qué?
Deberías estar usando RANK aquí:
WITH cte AS ( SELECT g.UnivId, RANK() OVER (ORDER BY COUNT(e.EmpId) DESC) rnk FROM Graduate g INNER JOIN Employee e ON g.EmpId = e.EmpId GROUP BY g.UnivId ) SELECT UnivId FROM cte WHERE rnk = 1;Tenga en cuenta que este enfoque también maneja bien los lazos, en caso de que ocurran.
El problema con su enfoque actual es que se está refiriendo a la subconsulta en la cláusula WHERE como si fuera una tabla independiente, que no lo es. Puede mover la subconsulta Temp a un CTE, y luego su enfoque puede funcionar:
WITH Temp AS ( SELECT G.UnivId, COUNT(*) as Num FROM Graduate G, Employee E WHERE G.EmpId = E.EmpId GROUP BY G.UnivId ) SELECT Temp.UnivId FROM Temp WHERE Temp.Num = (SELECT MAX(Temp.Num) FROM Temp);Debería ser más simple. Mueva su subconsulta a un CTE, luego ordene por num descendente y elija el resultado superior. No es necesario unirse a Graduate y Employee también.
Por cierto, temp es una palabra reservada, así que es mejor no usarla como identificador/nombre.
with tmp as ( select univid, count(*) as num from graduate group by univid ) select univid from tmp order by num desc limit 1;Creo que los CTE hacen que el código SQL sea más legible, pero puedes escribir lo mismo sin un CTE.
select univid from ( select univid, count(*) as num from graduate group by univid ) tmp order by num desc limit 1; Sin embargo, si los empates son un problema, es mejor que use el enfoque de rank de @TimBiegeleisen, aún sin la join .
Puede acceder a las columnas de la consulta a la que ha asignado un alias Temp , pero no puede seleccionarlas porque no ha creado una vista. Si desea crear una vista ad-hoc, use una cláusula WITH para esto.
Por cierto, no debe usar uniones separadas por comas. Esta fue la sintaxis utilizada en la década de 1980 y algunos años después hasta que las uniones explícitas ( [INNER] JOIN , LEFT [OUTER] JOIN , etc.) se convirtieron en el estándar SQL en 1992. ¿Por qué unirse a la tabla de empleados de todos modos?
Aquí hay una manera de resolver esto:
select univid, count(*) from graduate group by univid order by count(*) desc fetch first row with ties;Aquí está otro:
select univid, cnt from ( select univid, count(*) as cnt, max(count(*)) over () as max_cnt from graduate group by univid ) t where cnt = max_cnt;Y esto es lo que intentaste:
with t as ( select univid, count(*) as cnt from graduate group by univid ) select * from t where cnt = (select max(cnt) from t);