buscar las 3 fechas más antiguas en SQL

publicado por: Anonymous

Tengo un problema con una consulta.
La tabla tiene los siguientes campos:

Tabla1
--------+-----------+---------+------------------
Id      | Inicio    | Fin     | Descripcion
--------+-----------+---------+------------------

Y las reglas son:

  • Si algún inicio o fin es = ‘0000-00-00’ que me devuelva que hay fechas con ese valor.
  • Si algún inicio o fin es = ‘0001-01-01’ que me devuelva que hay fechas con ese valor
  • Y aparte necesito la fecha más antiguas que no sean ‘0000-00-00’ y ‘0000-00-000’ agrupada por descripción.

¿Es posible esto?

Ejemplo con datos:

Tabla1
--------+------------+------------+------------------
Id      | Inicio     | Fin        | Descripcion
--------+------------+------------+------------------
1       - 0000-00-00 - 0000-00-00 - 1
2       - 0001-01-01 - 0001-01-01 - 1
3       - 0000-00-00 - 0000-00-00 - 1
3       - 2016-10-20 - 0000-00-00 - 1
4       - 2016-07-10 - 0000-00-00 - 1
5       - 0000-00-00 - 2016-11-20 - 1
6       - 0000-00-00 - 2016-10-30 - 1
7       - 0000-00-00 - 0000-00-00 - 2
8       - 0001-01-01 - 0001-01-01 - 2
9       - 0000-00-00 - 0000-00-00 - 2
10      - 2016-10-20 - 0000-00-00 - 2
11      - 2016-07-10 - 0000-00-00 - 2
12      - 0000-00-00 - 2016-11-20 - 2
13      - 0000-00-00 - 2016-10-30 - 2

Lo que debería mostrar sería:

Producto 1 posee fechas en 0000-00-00, 0001-01-01, 2016-07-10 (Inicio)
y 2016-10-30 (Fin)

Y producto 2 lo mismo.

Tengo la siguiente consulta, pero no funciona correctamente:

SELECT MIN(inicio), MIN(fin), descripcion
FROM tabla1
GROUP BY descripcion

En PHP tengo lo siguiente:

if ($f['inicio'] != '0001-01-01' AND $f['inicio'] != '0000-00-00' AND $f['fin'] == '0000-00-00')
                {
                if ($diferencia >= 3)
                    {
                    echo '<td>"Tareas atrasadas!!"</td>';
                    }
                if ($diferencia <= 2)
                    {
                    echo '<td>"Sin atraso"</td>';
                    }
                }
                if ($f['ultimarealizazion'] == '0001-01-01')
                    {
                    echo '<td>"Sin atraso"</td>';
                    }
                else
                    {
                    echo '<td>"Sin asignaciones"</td>';

solución

Yo usaría lo consulta siguiente: (prefiero el SQL que propongo más abajito)

select producto,
       coalesce(max(case when inicio_o_fin = '0000-00-00' then 1 end), 0) as tiene_0,
       coalesce(max(case when inicio_o_fin = '0001-01-01' then 1 end), 0) as tiene_1,
       min(case when inicio_o_fin not in ('0000-00-00', '0001-01-01')
                     and tipo = 'inicio'
                then inicio_o_fin end) as min_inicio,
       min(case when inicio_o_fin not in ('0000-00-00', '0001-01-01')
                     and tipo = 'fin' 
                then inicio_o_fin end) as min_fin
  from (select descripcion as producto,
               inicio as inicio_o_fin,
               'inicio' as tipo
          from Tabla1
         union all
        select descripcion as producto,
               fin as inicio_o_fin,
               'fin' as tipo
          from Tabla1) t
 group by producto
 order by producto

En este caso, el resultado sería:

producto  tiene_0  tiene_1   min_inicio   min_fin
--------  -------  -------   ----------   ----------
   1         1        1      2016-07-10   2016-10-30
   2         1        1      2016-07-10   2016-10-30

Para las columnas tiene_0 y tiene_1, el resultado es 0 si no existe 0000-00-00 (o 0001-01-01 según el caso), y 1 si existe.

Con esos resultados, debería ser fácil para ti de usar tu código en PHP para transformar los datos en la frase:

Producto 1 posee fechas en 0000-00-00, 0001-01-01, 2016-07-10 (Inicio) y 2016-10-30 (Fin)

Edición: Mejor respuesta

Por favor, olvida la sentencia que sugerí arriba (aunque la voy a dejar para que puedas comparar). Prefiero la siguiente, que es mucho más sencilla, y solo necesita recorrer la tabla una vez:

select descripcion as producto,
       coalesce(max(case when inicio = '0000-00-00' or fin = '0000-00-00' then 1 end), 0) as tiene_0,
       coalesce(max(case when inicio = '0001-01-01' or fin = '0001-01-01' then 1 end), 0) as tiene_1,
       min(case when inicio not in ('0000-00-00', '0001-01-01') then inicio end) as min_inicio,
       min(case when fin not in ('0000-00-00', '0001-01-01') then fin end) as min_fin
  from Tabla1
 group by descripcion
 order by producto
Respondido por: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *