reemplazar - MySQL: obtenga MAX o GREATEST de varias columnas, pero con campos NULL
hacer un campo not null mysql (4)
Si date1
nunca puede ser NULL
, entonces el resultado nunca debe ser NULL
, ¿verdad? Entonces podría usar esto, si quiere que las fechas NULL
no se cuenten en los cálculos (o cambie el 1000-01-01
a 9999-12-31
, si quiere que los Null cuenten como el "fin de los tiempos"):
GREATEST( date1
, COALESCE(date2, ''1000-01-01'')
, COALESCE(date3, ''1000-01-01'')
) AS datemax
Estoy tratando de seleccionar la fecha máxima en tres campos diferentes en cada registro (MySQL) Entonces, en cada fila, tengo date1, date2 y date3: date1 siempre está lleno, date2 y date3 pueden ser NULL o vacíos. La sentencia GREATEST es simple y conciso, pero no tiene efectos en los campos NULL, por lo que esto no funciona bien:
SELECT id, GREATEST(date1, date2, date3) as datemax FROM mytable
Intenté también soluciones más complejas como esta:
SELECT
CASE
WHEN date1 >= date2 AND date1 >= date3 THEN date1
WHEN date2 >= date1 AND date2 >= date3 THEN date2
WHEN date3 >= date1 AND date3 >= date2 THEN date3
ELSE date1
END AS MostRecentDate
Mismo problema aquí: los valores NULL son un GRAN problema al devolver los registros correctos
Por favor, ¿tienes una solución? Gracias por adelantado....
Use COALESCE
SELECT id,
GREATEST(date1,
COALESCE(date2, 0),
COALESCE(date3, 0)) as datemax
FROM mytable
Actualización: Esta respuesta usó previamente IFNULL
que funciona, pero como Mike Chamberlain señaló en los comentarios, COALESCE
es en realidad el método preferido.
buuut, si todas las fechas son nulas? usted todavía quiere tener nulo como salida, ¿verdad? entonces necesitas esto
select nullif(greatest(coalesce(<DATEA>, from_unixtime(0)), coalesce(<DATEB>, from_unixtime(0))), from_unixtime(0));
Ahora, si ambos son nulos, obtienes nulo, si uno de ellos no es nulo, ambos no son nulos, obtienes lo mejor.
Esto es una locura, especialmente si lo va a usar varias veces, para esto, entonces puede querer crearlo como una función, como esta:
delimiter //
drop function if exists cp_greatest_date//
create function cp_greatest_date ( dateA timestamp, dateB timestamp ) returns timestamp
deterministic reads sql data
begin
# if both are null you get null, if one of them is not null of both of them are not null, you get the greatest
set @output = nullif(greatest(coalesce(dateA, from_unixtime(0)), coalesce(dateB, from_unixtime(0))), from_unixtime(0));
# santiago arizti
return @output;
end //
delimiter ;
Entonces puedes usarlo así
select cp_greatest_date(current_timestamp, null);
-- output is 2017-05-05 20:22:45
COALESCE
sus columnas de fecha antes de usarlas en GREATEST
.
La forma en que los manejes dependerá de cómo quieras lidiar con NULL
... ¿alto o bajo?