Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » Mysql »

Hacer un SELECT con limite 1 para dos códigos

Estas en el tema de Hacer un SELECT con limite 1 para dos códigos en el foro de Mysql en Foros del Web. Buenos días, tengo esta tabla: tabla1: id - integer - autonumérico codigo - integer fecha - datetime Con estos valores: 1 - 8 - 2014-05-07 ...
  #1 (permalink)  
Antiguo 07/05/2014, 02:34
 
Fecha de Ingreso: septiembre-2005
Mensajes: 522
Antigüedad: 19 años, 2 meses
Puntos: 0
Hacer un SELECT con limite 1 para dos códigos

Buenos días,

tengo esta tabla:

tabla1:

id - integer - autonumérico
codigo - integer
fecha - datetime


Con estos valores:
1 - 8 - 2014-05-07 10:00:00
2 - 8 - 2014-05-07 10:00:01
3 - 8 - 2014-05-07 10:00:02
4 - 10 - 2014-05-07 10:00:03
5 - 8 - 2014-05-07 10:00:04

Me gustaría obtener 1 registro del código 8 y un registro del código 10 en un mismo SELECT ordenados por fecha DESC

Resultado que necesito:

4 - 10 - 2014-05-07 10:00:03
5 - 8 - 2014-05-07 10:00:04


He probado haciendo union de la misma tabla pero no me funciona:

SELECT *
FROM tabla1
WHERE codigo=8

UNION ALL

SELECT *
FROM tabla1
WHERE codigo=10

ORDER BY fecha DESC
LIMIT 2;





Saludos
  #2 (permalink)  
Antiguo 07/05/2014, 02:40
 
Fecha de Ingreso: noviembre-2002
Mensajes: 50
Antigüedad: 22 años
Puntos: 0
Respuesta: Hacer un SELECT con limite 1 para dos códigos

Debes utilizar la clausula GROUP BY

en concreto

select *
from tabla
group by codigo

Así te saldrá el primero de cada código

Si quieres que te salga el último

select *
from (select * from tabla order by id desc)
group by codigo

(Está sin probar, por si falla algo, pero la solución va en éste sentido agrupando por GROUP BY)
  #3 (permalink)  
Antiguo 07/05/2014, 03:09
 
Fecha de Ingreso: septiembre-2005
Mensajes: 522
Antigüedad: 19 años, 2 meses
Puntos: 0
Respuesta: Hacer un SELECT con limite 1 para dos códigos

Hola,

en algún sitio tengo que indicarle que solamente quiero código 8 y código 10 no? Es decir, faltaría "where codigo=8 or código=10)

He probado lo siguiente y no funciona:

----------------------------------------------------
SELECT *
FROM tabla1
group by codigo
order by fecha desc;

Resultado:
4, 10, '2014-05-07 10:00:03'
1, 8, '2014-05-07 10:00:00'

Que faltaría "where codigo=8 or codigo=10" para que me diera únicamente el 8 y 10.
----------------------------------------------------
SELECT *
FROM (select * from test.tabla1 order by id desc)
group by codigo;

Esto da error: Every derived table must have its own alias
----------------------------------------------------



Con el group by tengo los dos registros pero no ordenados por fecha DESC


El resultado que necesito es:
4 - 10 - 2014-05-07 10:00:03
5 - 8 - 2014-05-07 10:00:04

Gracias por la respuesta
Saludos
  #4 (permalink)  
Antiguo 07/05/2014, 03:11
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Sabadell
Mensajes: 4.897
Antigüedad: 16 años, 8 meses
Puntos: 574
Respuesta: Hacer un SELECT con limite 1 para dos códigos

Mejor esto

Código MySQL:
Ver original
  1. FROM tabla1
  2. WHERE codigo=8
  3.  
  4.  
  5. FROM tabla1
  6. WHERE codigo=10
__________________
Quim
--------------------------------------------------
Ayudar a ayudar es una buena práctica!!! Y da buenos resultados.
  #5 (permalink)  
Antiguo 07/05/2014, 03:19
 
Fecha de Ingreso: septiembre-2005
Mensajes: 522
Antigüedad: 19 años, 2 meses
Puntos: 0
Respuesta: Hacer un SELECT con limite 1 para dos códigos

Cita:
Iniciado por quimfv Ver Mensaje
Mejor esto

Código MySQL:
Ver original
  1. FROM tabla1
  2. WHERE codigo=8
  3.  
  4.  
  5. FROM tabla1
  6. WHERE codigo=10

Hola,

usando esto me da error : Incorrect usage of UNION and ORDER BY

creo que solo se puede usar order by al final de todo tal como había indicado en el primer post.



Es tal como había dicho ffseno aunque faltaba el alias


SELECT *
FROM (SELECT * FROM tabla1 ORDER BY fecha desc) alias
WHERE codigo=8 or codigo=10
GROUP BY codigo;

Gracias por la rapidez.

Saludos
  #6 (permalink)  
Antiguo 07/05/2014, 03:43
 
Fecha de Ingreso: noviembre-2002
Mensajes: 50
Antigüedad: 22 años
Puntos: 0
Respuesta: Hacer un SELECT con limite 1 para dos códigos

utiliza la clausula where codigo in (8,10)
Hacer un union para eso parece un poco ilógico pero si te funciona ...
¿Qué harías si tuiveras más codigo que desearas incluir? El union no te serviría
  #7 (permalink)  
Antiguo 07/05/2014, 04:38
 
Fecha de Ingreso: septiembre-2005
Mensajes: 522
Antigüedad: 19 años, 2 meses
Puntos: 0
Respuesta: Hacer un SELECT con limite 1 para dos códigos

Hola,

no uso union, no funciona.

Uso lo que me has comentado:

SELECT *
FROM (SELECT * FROM tabla1 ORDER BY fecha desc) alias
WHERE codigo=8 or codigo=10
GROUP BY codigo;

Inicialmente me daba error porque me pedía un alias.

Ya está funcionando aunque..

en la tabla original que son 86 millones de registros, el select tarda muchísimo (lo he ejecutado hace más de 1 hora y sigue ejecutándose).

la tabla es innodb, con 21 campos y código y fecha están indexados

Saludos
  #8 (permalink)  
Antiguo 07/05/2014, 05:16
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Sabadell
Mensajes: 4.897
Antigüedad: 16 años, 8 meses
Puntos: 574
Respuesta: Hacer un SELECT con limite 1 para dos códigos

Esa subconsulta con ese numero de registros, no se yo.

En todo caso tendras los pertinentes indices, sobre codigo y fecha.

Aquí ofrecen esta solución
Código MySQL:
Ver original
  1. (
  2. FROM tabla1
  3. WHERE codigo=8
  4. LIMIT 1) Sbc1
  5.  
  6.  
  7. FROM tabla1
  8. WHERE codigo=10
  9. LIMIT 1) Sbc2
  10. ) derivedTable;

Obviamente si los codigos son mas se debería montar la query dinamicamente.
__________________
Quim
--------------------------------------------------
Ayudar a ayudar es una buena práctica!!! Y da buenos resultados.
  #9 (permalink)  
Antiguo 07/05/2014, 07:14
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 17 años
Puntos: 2658
Respuesta: Hacer un SELECT con limite 1 para dos códigos

Volvamos al principio:
Cita:
Con estos valores:
1 - 8 - 2014-05-07 10:00:00
2 - 8 - 2014-05-07 10:00:01
3 - 8 - 2014-05-07 10:00:02
4 - 10 - 2014-05-07 10:00:03
5 - 8 - 2014-05-07 10:00:04

Me gustaría obtener 1 registro del código 8 y un registro del código 10 en un mismo SELECT ordenados por fecha DESC

Resultado que necesito:

4 - 10 - 2014-05-07 10:00:03
5 - 8 - 2014-05-07 10:00:04
Por los datos que muestras, y el resultado que buscas, lo que quieres es el último regustro ingresado de cada uno de esos códigos.
Eso hay varias formas de obtenerlo, or ejemplo:
Código MySQL:
Ver original
  1. SELECT codigo, MAX(fecha) fecha
  2. FROM tabla
  3. WHERE codigo IN (8, 10)
  4. GROUP BY codigo

Código MySQL:
Ver original
  1. SELECT codigo, fecha
  2.     (SELECT codigo, fecha
  3.     FROM tabla
  4.     WHERE codigo IN (8, 10)
  5.     ORDER BY codigo, fecha) T1
  6. GROUP BY codigo
Esas serían las más simples.

Ahora bien, esto:
Cita:
en la tabla original que son 86 millones de registros (...)
Es información que deberías habernos dado desde el principio. En ese caso lo primero es asegurarse de los índices, y además no traer datos en el SELECT que no sean estrictamente necesarios.
Es decir, nada de hacer "SELECT * ...". Eso te matará la consulta.

¿QUé índices tienes y sobre qué campos está creado cada uno?

Habría, además, que asegurarse de que la query esté usando realmente el índice. Un EXPLAIN sería una buena idea para tu prueba.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)

Última edición por gnzsoloyo; 07/05/2014 a las 07:59
  #10 (permalink)  
Antiguo 09/05/2014, 13:03
 
Fecha de Ingreso: septiembre-2005
Mensajes: 522
Antigüedad: 19 años, 2 meses
Puntos: 0
Respuesta: Hacer un SELECT con limite 1 para dos códigos

Hola,

gracias por las respuestas.

Como he mencionado en el post anterior:

la tabla es innodb, con 21 campos. Código y fecha están indexados. Cuando hago SELECT no uso *.

El select:

Código MySQL:
Ver original
  1. SELECT codigo, MAX(fecha) fecha
  2. FROM tabla
  3. WHERE codigo IN (8, 10)
  4. GROUP BY codigo

Tarda 3 segundos, y me da el resultado que esperaba.

El segundo select:

Código MySQL:
Ver original
  1. SELECT codigo, fecha
  2.     (SELECT codigo, fecha
  3.     FROM tabla
  4.     WHERE codigo IN (8, 10)
  5.     ORDER BY codigo, fecha) T1
  6. GROUP BY codigo

Tarda menos de 1 segundo y también me da el resultado esperado.

Gracias por las respuestas.

En el caso de tener mas códigos, por ejemplo, 8,9,10,11,12 y 13. Debería usar el mismo web codigo in (8,9,10,11,12,13) o es mejor usar WHERE codigo=8 OR codigo=9...?

SAludos

Última edición por gnzsoloyo; 09/05/2014 a las 13:16
  #11 (permalink)  
Antiguo 09/05/2014, 13:19
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 17 años
Puntos: 2658
Respuesta: Hacer un SELECT con limite 1 para dos códigos

Cita:
En el caso de tener mas códigos, por ejemplo, 8,9,10,11,12 y 13. Debería usar el mismo web codigo in (8,9,10,11,12,13) o es mejor usar WHERE codigo=8 OR codigo=9...?
El comportamiento del IN varía de acuerdo al DBMS. En MySQL es más eficiente IN() que hacer la comparación con OR, en especial si el campo está indexado.
Si lo hicieras en Oracle podrías terminar saliendo por timeout.

En cualquier caso tienes que recordar que toda consulta con ORDER BY y/o GROUP BY resulta poco eficiente cuando se trata de centenares de miles o millones de registros. En ese caso es mejor realizar, si se puede, algún JOIN con otra tabla que permita reducir el numero de resultados a filtrar.

Te recomiendo estudiar el uso de EXPLAIN para analizar la performance de las consultas.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #12 (permalink)  
Antiguo 12/05/2014, 05:36
 
Fecha de Ingreso: septiembre-2005
Mensajes: 522
Antigüedad: 19 años, 2 meses
Puntos: 0
Respuesta: Hacer un SELECT con limite 1 para dos códigos

Hola,

incluso si el SELECT es así, es mejor usar IN en vez de WHERE id='', ejemplo:


//Este?
Código MySQL:
Ver original
  1. SELECT e.id, e.descripcion
  2. FROM estados AS e
  3. WHERE e.id_idioma=1;

//O este?
Código MySQL:
Ver original
  1. SELECT e.id, e.descripcion
  2. FROM estados AS e
  3. WHERE e.id_idioma IN (1);


Por ejemplo en este caso quiero todos los estados donde idioma es siempre 1.

Estando e.id_idioma indexado

Saludos

Última edición por gnzsoloyo; 12/05/2014 a las 07:17

Etiquetas: limite, registro, select, tabla
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 10:39.