Mostrando entradas con la etiqueta top. Mostrar todas las entradas
Mostrando entradas con la etiqueta top. Mostrar todas las entradas

jueves, 28 de julio de 2016

La crème de la crème (consultas TOP-N en Oracle)

En esta entrada hablaba de cómo seleccionar las N primeras filas de una tabla. En todos los casos (Informix, SQL Server, SQLite, Oracle), hacía una consulta básica y nos quedábamos con los 10 primeros resultados. Las filas en una tabla relacional no están ordenadas, por definición, lo cual significa que la consulta nos da las N primeras filas aleatorias, es decir, sin ordenar.

Pero la cosa cambia un poco si las queremos ordenadas, es decir los mejores resultados, las mejores notas, los mejores salarios, la crème de la crème... (o los peores).

Queremos los resultados crème de la crème

Esto significa sacar las N filas primeras (o mínimas) o las N filas últimas (o máximas), lo que se denomina a veces consultas TOP-N (TOP-N queries, por si queréis buscarlo en inglés).

En el caso de SQLite3 podíamos poner la cláusula LIMIT después del ORDER BY, como se explicaba en aquella entrada. Pero en ORACLE no existe la cláusula LIMIT, así que habrá que hacerlo de alguna otra manera.

En principio, utilizando la columna "mágica" ROWNUM, si hacemos lo siguiente:

SELECT * FROM TABLA WHERE ROWNUM <= 100

estamos obteniendo 100 filas aleatorias. Uno podría pensar que entonces, para obtener las TOP-100 filas bastaría con añadir una condición ORDER BY, tal que así:

SELECT * FROM TABLA WHERE ROWNUM <= 100 ORDER BY CAMPO

Pero eso no funcionaría. Lo que nos estaría dando son 100 filas aleatorias, y una vez seleccionadas (y no antes), nos las mostraría ordenadas por el CAMPO indicado. Pero eso no significa que nos esté dando las 100 filas PRIMERAS (según en el orden indicado) de la tabla. El problema es que el valor de ROWNUM se está asignando justo al seleccionar la fila, y la operación ORDER BY se aplica después.

Así pues, la forma correcta de hacerlo en Oracle es intercalar una SELECT dentro de otra:

SELECT * FROM (la-consulta-original) WHERE ROWNUM <= 100

Es decir, para el caso que nos ocupa:

SELECT * FROM (SELECT * FROM TABLA ORDER BY CAMPO) WHERE ROWNUM <= 100


Ale, problema resuelto. A seguir tecleando.

--

Nota: no confundir ROWNUM con ROWID. Ambas son columnas que asigna ORACLE automáticamente, pero no significan lo mismo.

Si queréis una explicación muy buena y bastante detallada acerca de la diferencia entre ROWNUM y ROWID y cómo utilizar ROWNUM para consultas TOP-N y para resultados paginados, echadle un vistazo a este artículo

http://www.epidataconsulting.com/tikiwiki/tiki-read_article.php?articleId=63

viernes, 31 de octubre de 2014

Cómo saber cuánto tiempo lleva encendido el ordenador

A veces queremos saber cuánto tiempo lleva encendido un ordenador. ¿Cómo podemos hacer esto?


Figura 1. ¿Qué hora es en este reloj hebreo? (Visto en Praga)

1. Respuesta corta

En Linux, MacOs, HP-UX y versiones varias de UNIX: comandos "w", "uptime" y "top"

En Windows: comando "systeminfo"


2. Respuesta larga

2.1 Aplicaciones
Simplemente, queremos saber cuánto lleva encendido el equipo. O bien, somos los responsables de un servidor, y queremos saber si el servidor se ha reiniciado por la noche, por ejemplo. O hemos llegado a casa y hemos pillado a nuestro hijo todo viciado matando orcos a diesto y siniesto. A pesar de que le dijimos que sólo podía jugar una hora al día, tiene los ojos inyectados en sangre, rojos como dos tomates, sospechamos algo y no nos creemos lo que nos jura y perjura de que acaba de encenderlo "hace ná". Queremos comprobar, en todos estos casos, cuánto tiempo lleva el ordenador encendido.

2.2 En Linux
Si el equipo está ejecutando un Linux, bastará con teclear bien poco, una sola letra y hecho. El comando "w" nos da la información que queremos en la primera línea de su salida. Como una imagen vale más que mil palabras, ahí va un ejemplo:

Figura 2. Este equipo lleva 4 días, 4 horas y 14 minutos encendido

Tenemos más información adicional en ese comando, pero la que nos interesa está en la primera línea, junto con los datos de carga del procesador en el último minuto, últimos 5 y últimos 15 minutos. Si lo único que queremos es la información de esa primera línea sin mostrar la otra información (la de los usuarios que hay conectados), entonces podemos hacer un grep para solo mostrar la primera línea, así:

$ w | grep "load average"

(ojo, esto podría sacar también otras líneas que contuvieran esa cadena de texto)

O bien, y mejor aún, ejecutar el comando "uptime", que muestra únicamente esa primera línea.

Figura 3. Uptime como un "w" limitado a la primera línea

Otro comando que está en todos los *NIX modernos y que da esta misma info (más un montón de información adicional) es el comando top. Así, si ejecutamos

$ top

Obtendremos algo así

Figura 4. El comando "top" también nos dice cuánto tiempo lleva encendido el ordenador

Aunque a decir verdad, a mí me gusta más la versión de "top con colorines", llamada "htop" (también existen "atop" y otros...)


Figura 5. htop: top con maquillaje de colores

2.3 En Windows
En todas las versiones de Windows desde XP tenemos el comando "systeminfo", que se encarga de recoger un montón de información del equipo, entre ella la que nos interesa. En XP salen tantas líneas que se pierde la información por arriba, y en mi caso, el buffer de la ventana de comandos no conserva todas las líneas cuando vuelvo hacia atrás, así que he tenido que redirigir la salida al comando "less" para que me la muestre paginada

c:\> systeminfo | less

También podríamos haber redirigido esta salida a un fichero de texto y luego abrirlo con el bloc de notas.

Al ejecutar systeminfo, tras unos segundos, durante los cuales vemos unos mensajes indicando qué está haciendo el programa, tenemos una salida tal que así

Figura 6. Salida de "systeminfo" en Windows XP

donde podemos ver que el equipo lleva 4 días y casi 11 horas encendido (penúltima línea de la imagen).


2.4 Mi script personal
Como me gusta la salida en una única línea que proporciona el comando uptime de Linux, me he hecho mi pequeño script en Windows, lo he colocado en la carpeta de utilidades que tengo incluida en el PATH, para poder invocarlo igual que lo hago en Linux. Lo he llamado "uptime.cmd", y su contenido es sencillamente las siguientes dos líneas

Figura 7. Script para implementar un uptime

(el comando "find" es equivalente al grep de Linux)

Y ahora sí, en mi consola de Windows

Figura 8. Uptime disponible también en Windows

Y así no tengo que pensar si estoy en Linux o en Windows, en ambos sitios puedo escribir uptime y respuesta inmediata.

Y ahora pregunto yo...
Dicho todo esto, ¿alguien sabe cómo ver en un smartphone con Android el tiempo que lleva funcionando desde el último reinicio? Seguramente no sea muy complicado, pero le he dedicado unos minutos y no he hallado la respuesta rápidamente. Voy a seguir buscando.

Ahí queda la pregunta


viernes, 13 de enero de 2012

SQL - Seleccionar sólo las primeras N filas

El otro día metí la pata haciendo un SELECT genérico de una tabla de la que desconocía el tamaño. El procesador se puso casi al 100% durante 5 minutos, y el disco duro no dejaba de rascar. Los usuarios que compartían (sufrían) conmigo el acceso a la BD estuvieron experimentando un rendimiento pésimo durante esos 5 minutos (bueno, los pocos que intentaron trabajar en ese período), que a mí se me hicieron eternos. El problema es que la tabla tenía casi 2 millones de registros y esto fue er... bueno... "un poco" pesado. Encima, el resultado fue a una página web, así que os podéis imaginar el tamaño del "ascensor" (el recuadro) de la barra de desplazamiento. Casi no se podía pinchar en él de pequeño que se quedó.

El caso es que me interesaba simplemente ojear el contenido de esa tabla, me hubiera bastado con recuperar unos pocos registros, digamos, unos 100 para hacerme una idea de su contenido. Bueno, pues eso se puede hacer sin necesidad de poner filtros a los datos (cosa que en su momento no podía hacer pues no tenía ni idea de los campos y datos de la tabla).

En ORACLE
SELECT * FROM TABLA WHERE ROWNUM <100

En MS SQL Server y en SYBASE

SELECT TOP 10 * FROM TABLA

En INFORMIX
SELECT FIRST 100 * FROM TABLA


Actualización 02/09/2014 para incluir SQLite3, que me ha hecho falta hoy. Hay que añadir LIMIT(N) al final de la consulta

En SQLite3
SELECT * FROM TABLA LIMIT(100)

Si hubiera cláusulas WHERE u ORDER BY, hay que poner la opción LIMIT al final de todo, o sea:

SELECT * FROM TABLA WHERE CONDICION ORDER BY CAMPO LIMIT(100)
Related Posts Plugin for WordPress, Blogger...