varlena
varlena
PostgreSQL Training,
Consulting & Support
General Bits
By A. Elein Mustain


06-Oct-2003 Edición: 46

Archives | General Tidbits | Google General Bits | Docs | Castellano | Português | Subscriptions | Notifications

General Bits General Bits es una publicación periódica escrita con información desde la lista de PostgreSQL, pgsql-general.
Para saber más sobre pgsql-general y PostgreSQL, visite www.PostgreSQL.org.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Respuestas al Examen
¡Nota máxima para todos los que trataron! 03-Oct-2003

  • 1. ¿Qué retorna SELECT coalesce( x, y ); cuando:
      coalesce() retorna el primer argumento que no es NULL.
    • a. x es NULL, y es 16
      • coalesce(NULL,16) retorna 16
    • b. x es 16, y es NULL
      • coalesce(16,NULL) retorna 16
    • c. x es NULL, y es NULL
      • coalesce(NULL,NULL) retorna NULL
    • d. x es 16, y es 17
      • coalesce(16,17) retorna 16

  • 2. ¿Usarán un índice estas cláusulas WHERE si existe en la columna?
      La mayoría de estas cláusulas WHERE tienen tipos de datos diferentes en las expresiones. Cuando es necesario convertir un tipo de dato, usualmente no se usa el índice.
    • a. WHERE timestamp_value = '12/31/59'
      • No. Un timestamp y una cadena de texto son tipos diferentes.
    • b. WHERE bigint_value = 3
      • No. Un bigint y un integer son tipos diferentes.
    • c. WHERE text_value LIKE '% the %'
      • No. Las cláusulas LIKE deben recorrer la tabla completa.
    • d. WHERE text_value in ( 'val_uno', 'val_dos', 'val_tres')
      • No. Las cláusulas IN, tal como las cláusulas OR, deben recorrer la tabla completa.
    • e. ¿Cuál dará un resultado inesperado?
      • a. El texto será convertido en un timestamp, no un date. Si espera que un timestamp sea truncado al valor de la fecha, se equivoca. Los timestamp completos rara vez coinciden con una fecha sin horas, minutos y segundos.

  • ¿Cuál será la cláusula ORDER BY cuando desee ordenar los NULLs de una columna al principio, pero que el resto de las columnas conserve su orden regular?
      d. ORDER BY column IS NOT NULL ASC, column
      o bien ORDER BY COLUMN IS NULL DESC, column
    • a. ORDER BY NULL
    • b. ORDER BY columna WITH NULL, columna
    • c. ORDER BY columna IS NOT NULL ASC
    • d. ORDER BY columna IS NOT NULL DESC, columna
    • e. ORDER BY columna

  • 4. En postgresql.conf, max_fsm_relations debería definirse como
      c. La cantidad total de tablas en todas las bases de datos.
    • a. 10
    • b. El número máximo de conexiones permitidas
    • c. La cantidad total de tablas en todas las bases de datos
    • d. El tamaño de cache libre en el disco duro

  • 5. El tipo timestamp with timezone se almacena con:
      a. UTC (note que el huso horario de entrada no es almacenado).
    • a. huso horario UTC
    • b. el huso horario del servidor
    • c. el huso horario del cliente
    • d. el huso horario especificado

  • 6. ¿Cuales de las siguientes palabras no deberían usarse como identificador en PostgreSQL?
      DEFAULT, IS, PRIMARY, y SOME no deben ser usados como identificadores. Las palabras reservadas de PostgreSQL y SQL se encuentran listadas en:
      • 7.3 Users Guide en el Apéndice B
      • 7.4 Capítulo 8 (Apéndices) Apéndice B en la documentación de la versión 7.4.
      ARE BEGIN CURRENT_ROLE DEFAULT
      IS MOVE NOT OFFSET
      OPERATOR PRIMARY SOME UNDER

  • 7.1 RULES deberían ser usadas para funcionalidad aplicable a:
  • 7.2 TRIGGERS deberían ser usados para funcionalidad aplicable a:
      RULES operan en la consulta completa, y se usan para crear las vistas. TRIGGERS operan registro por registro, y se implementan usando funciones.
    • a. una consulta
    • b. cada registro
    • c. vistas (views)
    • d. funciones

  • 8. Una función plpgsql se ejecuta
      Todas las funciones de lenguajes procedurales se ejecutan en el proceso servidor, también conocido como backend.
    • a. en el servidor
    • b. en la aplicación cliente
    • c. en psql
    • d. en cualquiera, el cliente o el servidor

  • 9. Una función creada con IMMUTABLE significa que
      b. la función siempre retornará los mismos resultados para los mismos argumentos
    • a. la función nunca cambiará
    • b. la función siempre retornará los mismos resultados para los mismos argumentos
    • c. la función nunca arrojará un error
    • d. la función retorna null si recibe algún argumento null

  • 10. Una función creada con STRICT significa que
      c. no se ejecutará si recibe algún argumento null
    • a. no debería ser guardada en cache
    • b. debería arrojar un error ante cualquier falla
    • c. no se ejecutará si recibe algún argumento null
    • d. siempre retornará un resultado no null

Contribuyó: elein at varlena.com

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Redirigiendo Errores
[SQL] Capturing pgsql ERRORS/NOTICES to file 26-Sep-2003

Cuando ejecuta psql desde el shell puede controlar tanto la salida estandar como la salida de error. Psql también le ayudará a formatear la salida. A continuación se presentan algunos ejemplos del uso de psql desde el shell.

Redirigir la salida de las consultas.

	psql -c "select * from mytable;" > query.out 
Redirigir la salida de error al mismo archivo que la salida estándar.
	psql -c "select * from mytable;" > query.out 2>&1 
Redirigir la entrada de consultas.
	psql -c "select * from mytable;" < query.sql 
Entrada de consultas en línea. Asegúrese que la marca de término empieza en la primera columna
	psql << QRY_END
	update mytable set prod_count = prod_count -1 where prod_id = 117;
	QRY_END
Archivo con valores separados por comas.
-A elimina el alineamiento. -t elimina los encabezados de tabla y los nombres de columna.
	psql -At -F ','  -c "select * from mytable;" > query.csv
Salida HTML.
Más útil si se llama desde un cliente perl o php para una aplicación web.
	psql -H -c "select * from mytable" 

Para mayor información sobre la redirección y programación del intérprete de comandos, vea man del intérprete que utilice. Estos ejemplos usan bash pero funcionan en la mayoría de los intérpretes.

Para mayor información sobre las capacidades de formateo de psql, vea man psql o la PostgreSQL Reference Guide, en la sección Client Applications.

Contribuyeron: George Weaver georgew1 at mts.net, Josh Berkus josh at agliodbs.com, Wei Weng wweng at kencast.com, elein at varlena.com

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Qué puede mostrar DISTINCT ON
[GENERAL] difference when using 'distinct on' 12-Sep-2003

El calificador DISTINCT a una sentencia SELECT le permite eliminar duplicados de un resultado. Usado en conjunción con una cláusula ORDER BY puede entregarle información interesante acerca de sus datos.

Esta definición de tabla será usada como ejemplo. Contiene dos escuelas, tres exámenes en dos temas y seis estudiantes.

	create table fortysix (
	   school      text,
	   subject     text,
	   test        integer,
	   student_id  integer,
	   score       integer );

Dado que todos los registros son únicos (asumiendo que no hay errores en el ingreso de datos), la siguiente sentencia entregará todos esos registros.

	SELECT DISTINCT school, subject, test, student_id, score
	FROM fortysix;
Esto no es particularmente útil. Sin embargo, si limita la lista de salida puede saber qué escuelas están involucradas, qué temas están involucrados y qué estudiantes están involucrados.
	=# -- Qué escuelas están involucradas
	=# select distinct school from fortysix;
	 school 
	--------
	 Carter
	 Ohlone
	(2 rows)
	
	=# 
	=# -- Qué temas están involucrados
	=# select distinct subject from fortysix;
	 subject 
	---------
	 Math
	 Reading
	(2 rows)
	
	=# 
	=# -- Qué estudiantes estuvieron involucrados en cada escuela
	=# select distinct school, student_id from fortysix;
	 school | student_id 
	--------+------------
	 Carter |       1024
	 Carter |       1025
	 Carter |       1026
	 Ohlone |       1027
	 Ohlone |       1029
	 Ohlone |       1400
	(6 rows)

Usando DISTINCT ON (), especialmente con una cláusula ORDER BY puede entregar aún más información. Las columnas listadas entre paréntesis indican los valores que deben ser únicos. Para controlar cuales registros son listados, puede ordenar por lo que desee; además debe incluir las columnas DISTINCT en la cláusula ORDER BY. En el primer caso, se ordena descendentemente por puntaje para encontrar el registro con el puntaje más alto.

	=# -- Quien obtuvo el puntaje más alto en cualquier examen, en
	=# -- cada tema, en cada escuela.
	=# select distinct on (school, subject) school, subject, test, student_id, score
	-# from fortysix
	-# order by school, subject, score desc;
	 school | subject | test | student_id | score 
	--------+---------+------+------------+-------
	 Carter | Math    |    1 |       1026 |   100
	 Carter | Reading |    1 |       1026 |   100
	 Ohlone | Math    |    3 |       1400 |    97
	 Ohlone | Reading |    3 |       1400 |   100
	(4 rows)
	
	=# -- Quien obtuvo el puntaje más alto en cada examen en cada
	=# -- tema en cada escuela.
	=# select distinct on (school, subject, test) 
	-#    school, subject, test, student_id, score
	-# from fortysix
	-# order by school, subject, test, score desc;
	 school | subject | test | student_id | score 
	--------+---------+------+------------+-------
	 Carter | Math    |    1 |       1026 |   100
	 Carter | Math    |    2 |       1026 |    99
	 Carter | Math    |    3 |       1026 |   100
	 Carter | Reading |    1 |       1026 |   100
	 Carter | Reading |    2 |       1026 |   100
	 Carter | Reading |    3 |       1026 |    99
	 Ohlone | Math    |    1 |       1027 |    92
	 Ohlone | Math    |    2 |       1400 |    95
	 Ohlone | Math    |    3 |       1400 |    97
	 Ohlone | Reading |    1 |       1027 |    99
	 Ohlone | Reading |    2 |       1400 |    97
	 Ohlone | Reading |    3 |       1400 |   100
	(12 rows)
	
	=# -- Qué estudiante obtuvo el puntaje más alto de todos los exámenes
	=# -- en cada tema
	=# select distinct on (subject) school, subject, student_id, score
	-# from fortysix
	-# order by subject, score desc;
	 school | subject | student_id | score 
	--------+---------+------------+-------
	 Carter | Math    |       1026 |   100
	 Carter | Reading |       1026 |   100
	(2 rows)
En el tercer ejemplo, sólo un estudiante fue seleccionado para cada tema, aunque más de uno puede haber obtenido el puntaje máximo.

DISTINCT ON () puede ser usado de manera similar a una cláusula GROUP BY, pero no se requiere una función de agregación. Note que debe incluir las columnas que aparecen en DISTINCT nuevamente en la lista de resultados si desea que aparezcan en la salida. Note además que no hay una coma (,) que separe la cláusula DISTINCT de la lista de resultados.

Ponga mucho atención a las sentencias en lenguaje natural que describen las consultas; ellas indican cómo construirlas. En la segunda consulta, la pregunta es:

¿Quién obtuvo el más alto puntaje en cada puntaje en cada tema en cada escuela?
El superlativo más alto (o más bajo) indica cuál columna ordenar, y en qué dirección. La palabra cada indica la agrupación. En castellano, cada examen en cada tema en cada escuela comúnmente corresponde a la agrupación en el orden inverso: escuela, tema, examen. En inglés sucede lo mismo.
	=# select distinct on (school, subject, test) 
	-#    school, subject, test, student_id, score
	-# from fortysix
	-# order by school, subject, test, score desc;

Contribuyeron: Johnson, Shaunn SJohnson6 at bcbsm.com, Bruno Wolff III bruno at wolff.to, Stephan Szabo sszabo at megazone.bigpanda.com, elein at varlena.com

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Trucos usando Secuencias para Granularidad Estadística
[SQL] Result set granularity.. 27-Sep-2003

Por razones estadísticas, puede desear muestrear un conjunto de datos en lugar de calcular los resultados usando el conjunto completo. Por ejemplo, puede desear usar uno de cada cinco registros.

Puede hacer esto usando una secuencia temporal. Cree las secuencias temporales y seleccione el siguiente valor para cada registro de la consulta. Haga esto en una subconsulta, y en el filtro principal, escoja usando el valor de la secuencia módulo 5.

	CREATE TEMP SEQUENCE number;
	SELECT * FROM ( 
	   SELECT *, nextval('number') AS number FROM datatable ) foo
	WHERE foo.number % 5 = 0;

Si desea cada quinto valor de una secuencia ordenada, simplemente ordene usando la columna apropiada.

Contribuyeron: Rasmus Aveskogh rasmus at defero.se, Harald Fuchs nospam at sap.com, scott.marlowe scott.marlowe at ihs.com

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Sobre las Horas en una Transacción
[SQL] now() in loop statement 29-Sep-2003

Las diferencias entre las funciones de la hora de reloj y la hora de la transacción fueron cubiertas anteriormente en la edición #16. La pregunta resurge de vez en cuando, de modo que aquí se presenta una mayor explicación en términos de sentencias y transacciones.

Las funciones de marcas temporales en PostgreSQL son:

funciónValorTipo de Dato
current_timestampHora y Fecha de Inicio de Transaccióntimestamp with time zone
localtimestampHora y Fecha de Inicio de Transaccióntimestamp without time zone
current_dateFecha de Inicio de Transaccióndate
current_timeHora de Inicio de Transaccióntime with time zone
localtimeHora de Inicio de Transaccióntime without time zone
now()Hora y Fecha de inicio de Transaccióntimestamp with time zone
'now' Hora y Fecha de inicio de transaccióntimestamp
timeofday()Hora y fecha de relojtext
Es decir, si desea la hora de reloj, use timeofday(). Si el tiempo de inicio de transacción es adecuado, úselo, porque es algunos microsegundos más rápido.

Todas estas funciones retornan el momento en que la transacción en curso comenzó como timestamp, time o date, excepto timeofday(), la cual retorna la hora actual como un campo de texto.

Para hacer que timeofday() retorne un timestamp o date, aplíquele una conversión a timestamp o date. Para que retorne un dato de tipo time, aplíquele una conversión a timestamp y luego a time.

ConversiónValor
select timeofday()::timestamp;2003-10-04 19:32:58.236439
select timeofday()::date;2003-10-04
select timeofday()::timestamp::time;19:33:14.039576

Si tiene una de las funciones de tiempo en una cláusula DEFAULT para alguna columna, la hora se pondrá usando el momento de inicio de la transacción del INSERT. Cuando se use estas funciones en un bloque de transacción, las referencias a todas ellas tendrán el mismo valor. Esto es muy útil cuando se trata de sincronizar horas en un conjunto de registros. En particular, un trigger es parte de la transacción de la sentencia SQL que lo invoca, por lo que cualquier referencia a una función de tiempo de transacción tendrá el mismo valor que cualquier otra parte en la sentencia original.

Contribuyeron: Kerv keresztes_m at yahoo.com, Tomasz Myrta jasiek at klaster.net, Dan Langille dan at langille.org, Christoph Haller ch at rodos.fzk.de


Comments and Corrections are welcome. Suggestions and contributions of items are also welcome. Send them in!.
Copyright A. Elein Mustain 2003, 2004,2005

Google
Search General Bits & varlena.com Search WWW