|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Los registros para la Convención Open Source 2004 de O'Reilly (OSCON), a celebrarse en Portland, Oregon, USA, entre el 26 y el 30 de julio de 2004. Para aquellos de nosotros en o cerca de USA, esta es LA conferencia de PostgreSQL a la cual asistir. Gran parte de la gente de PostgreSQL estará allí. Tendrás la oportunidad de encontrarte cara a cara con tus desarrolladores y contribuyentes favoritos. PostgreSQL tendrá un sitio y una sesión birds-of-a-feather. Por favor contáctame si planeas venir y quieres saber qué tenemos planeado y cómo puedes unirte al resto del grupo. Te puede interesar sintonizar la lista de correo pgsql-advocacy para recibir parte de la discusión pública de PostgreSQL en OSCON. El PostgreSQL Track estará lleno de excelentes presentaciones de una buena variedad de personas muy impresionantes. Recomiendo asistir a todas ellas sin ninguna duda. Pero no te pierdas el panel de discusión acerca de Replicación. Los tutoriales serán lunes y martes, antes de la conferencia abierta. Están listados al final de esta tabla e incluyen sesiones de Joe Conway, Greg Sabino Mullane y quien escribe.
El NLUUG, de Holanda, está auspiciando una Conferencia de Open Source para los Negocios, en Ede, a celebrarse en De Reeshorst Hotel el 27 de mayo de 2004. Para mayor información sobre la conferencia, visite http://www.nluug.nl/events/vj04/ Elein Mustain hablará sobre Extensibilidad de PostgreSQL, usada en Análisis Predictivo, Biotecnología y GIS. Habrá muchas charlas en inglés y la mayoría de la gente también hablará inglés.
Para obtener los resultados de dos funciones de agregación separadas, ellas deben ir en subconsultas. Por ejemplo, para obtener la cantidad de filas de cada valor de la llave foránea main_id en la tabla A y en la tabla B, la consulta será: SELECT id, (SELECT COUNT(*) FROM sub_a WHERE sub_a.main_id=main.id), (SELECT COUNT(*) FROM sub_b WHERE sub_b.main_id=main.id) FROM main ORDER BY id; Las consultas de agregación se ejecutan en la lista de resultados. Cada subconsulta se ejecuta una vez para cada id de la tabla principal. Esta no es una consulta rápida, pero obtiene los resultados. Con tablas pequeñas, se puede usar esta técnica en consultas más complejas. Por ejemplo, dadas tablas con partidos de rugby y una tabla de equipos, podemos calcular cuántos juegos jugó cada equipo y cuántos juegos ganó, en una sola consulta. En esta consulta, el equipo podría estar en la tabla de partidos como team1 o team2. Hacemos la agregación en la consulta más pequeña posible con la tabla de equipos (teams), y mezclamos con las tablas de tipos de equipos (ttypes) y áreas (areas) en el resultado. Pero en cada extremo queremos eliminar aquellos equipos que no jugaron ningún partido, y queremos ordenar según el número de partidos jugados. select tname, matches, won, ttype, area from ( (select tname, tykey, akey, ((select count(*) from tmatches where team1 = sname ) + (select count(*) from tmatches where team2 = sname ) ) as matches, ((select count(*) from tmatches where team1 = sname and score1 > score2 ) + (select count(*) from tmatches where team2 = sname and score2 > score1 ) ) as won from teams) foo JOIN ttypes ty USING (tykey) JOIN areas USING (akey) where matches <> 0 order by matches desc; tname | matches | won | ttype | area ------------------------------------+---------+-----+-------------------+---------------- Berkeley All Blues | 23 | 15 | Club | Pacific Coast USA U23 National Team | 21 | 6 | National/All Star | All Women's All Star 7s Pacific | 16 | 14 | National/All Star | Pacific Coast Women's All Star 7s Atlantic | 16 | 9 | National/All Star | Mid-Atlantic Women's All Star 7s Northeast | 16 | 7 | National/All Star | Northeast Women's All Star 7s West | 16 | 6 | National/All Star | West Women's All Star 7s So California | 15 | 2 | National/All Star | So California Women's All Star 7s Midwest | 15 | 8 | National/All Star | Midwest Beantown | 14 | 8 | Club | Northeast Minnesota Valkyries | 14 | 8 | Club | Midwest New York | 13 | 7 | Club | Northeast Twin Cities Amazons | 11 | 5 | Club | Midwest Women's All Star 7s South | 10 | 4 | National/All Star | South Atlanta Harlequins | 8 | 3 | Club | South Washington Furies | 8 | 3 | Club | Mid-Atlantic Emerald City Mudhens | 8 | 1 | Club | Pacific Coast UCLA | 8 | 1 | Club | So California De todas maneras, esto sólo se puede usar en tablas lo suficientemente pequeñas como para permitir esperar los resultados. Y este ejemplo también muestra los beneficios de vistas bien definidas: claramente el SQL anidado puede ser difícil de leer. Esto podría ser simplificado con una vista. Es posible hacer una gran variedad de consultas tipo reporte usando esta técnica. Puedes incluir en la lista final de resultados el número total de equipos, la cantidad de partidos jugados por cada equipo, la cantidad de partidos ganados, puedes calcular los porcentajes de partidos ganados vs. jugados. Cuando las consultas involucran tablas más grandes, puedes considerar agrupar las cantidades en tablas de agregación. Esto puede ir calculándose usando un trigger en la tabla original; en ese caso, siempre tendrás los resultados listos para ser examinados y mezclados en la consulta final para efectuar más cálculos u otras agregaciones.
Para obtener una consulta TopN de un nivel en una consulta SQL, simplemente ordena descendentemente la columna y limita el resultado en N. elein=# select id from table70 order by id desc limit 5; id ---- 19 18 17 16 15 (5 rows) Esta consulta se complica bastante más cuando lo que realmente quieres es obtener los TopN agrupados según otro campo. La discusión en este tópico involucró UNIONs, subconsultas de cuatro niveles, JOINs y el uso de la función ROW_NUMBER(). (La función ROW_NUMBER es simplemente un contador de filas de salida. Puede ser escrito en plpython (mira en la Edición #16, que contiene mi charla de plpython) o en otros lenguajes procedurales, pero PostgreSQL no la soporta directamente. Rod Taylor indicó que está en la especificación 6.10 de SQL200N, pero Tom Lane arguyó que si el nuevo estándar ni siquiera tiene un número de año todavía, difícilmente se puede esperar que las implementaciones reales lo soporten.) El problema es como sigue. Dada esta tabla: Column | Type | Modifiers ----------+--------------+----------- id | integer | PRIMARY KEY query | integer | checksum | character(2) | score | integer |muestre los primeros N puntajes (score) agrupados por query. La salida se parecerá a esta, donde se muestran las filas que contienen los primeros 2 puntajes para cada query. id | query | checksum | score ----+-------+----------+------- 1 | 1 | aa | 10 11 | 1 | bb | 10 5 | 2 | cc | 11 12 | 2 | cc | 11 3 | 3 | cc | 11 9 | 3 | bb | 11 (6 rows) Greg Sabino Mullane mostró un ejemplo detallado usando secuencias, y Rod Taylor dio una solución usando ROW_NUMBER(). Yo decidí tratar de entregar el resultado usando una función que retornara conjuntos de filas.
El tipo del resultado debe ser creado de antemano. La función se creó
de manera que se pueda entregar N, el número de resultados que se quieren
obtener en cada grupo. Como hice en el artículo anterior, decidí usar
selects anidados, usando la técnica
Para cada query, obtenemos las primeras N filas.
CREATE TYPE topscores AS (id integer, query integer, checksum char(2), score integer); CREATE OR REPLACE FUNCTION topscores(integer) RETURNS SETOF topscores AS ' DECLARE t topscores%ROWTYPE; r RECORD; q RECORD; n alias for $1; BEGIN FOR q IN SELECT distinct query from table70 order by query LOOP FOR t IN SELECT id , query, checksum, score FROM table70 where query = q.query ORDER BY query, score DESC LIMIT n LOOP RETURN NEXT t; END LOOP; END LOOP; RETURN; END; ' language 'plpgsql'; El SQL completo de este ejemplo está disponible para descargar.
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comments and Corrections are welcome. Suggestions and contributions of items are also welcome. Send them in!. Copyright A. Elein Mustain 2003, 2004,2005 |