J'essaie de sélectionner la date maximum dans trois champs différents dans chaque enregistrement (MySQL) Ainsi, dans chaque ligne, j'ai date1, date2 et date3: date1 est toujours rempli, date2 et date3 peuvent être vides ou nuls L’instruction GREATEST est simple et concise mais n’a aucun effet sur les champs NULL. Elle ne fonctionne donc pas bien:
SELECT id, GREATEST(date1, date2, date3) as datemax FROM mytable
J'ai aussi essayé des solutions plus complexes comme celle-ci:
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
Même problème ici: les valeurs NULL sont un très bon problème pour retourner les bons enregistrements
S'il vous plaît, avez-vous une solution? Merci d'avance ....
Utilisez COALESCE
SELECT id,
GREATEST(date1,
COALESCE(date2, 0),
COALESCE(date3, 0)) as datemax
FROM mytable
Mise à jour: Cette réponse utilisait précédemment IFNULL
qui fonctionne, mais comme Mike Chamberlain l'a souligné dans les commentaires, COALESCE
est en fait la méthode préférée.
Si date1
ne peut jamais être NULL
, le résultat ne devrait jamais être NULL
, n'est-ce pas? Vous pouvez ensuite utiliser ceci si vous souhaitez que les dates NULL
ne soient pas comptées dans les calculs (ou remplacez le 1000-01-01
par 9999-12-31
si vous souhaitez que Nulls compte comme "fin du temps"):
GREATEST( date1
, COALESCE(date2, '1000-01-01')
, COALESCE(date3, '1000-01-01')
) AS datemax
COALESCE
vos colonnes de date avant de les utiliser dans GREATEST
.
La façon dont vous les manipulerez dépendra de la manière dont vous souhaitez gérer NULL
.. haut ou bas?
buuut, si toutes les dates sont nulles? vous voulez toujours avoir null comme sortie, non? alors vous avez besoin de ça
select nullif(greatest(coalesce(<DATEA>, from_unixtime(0)), coalesce(<DATEB>, from_unixtime(0))), from_unixtime(0));
Maintenant, si les deux sont nuls, vous obtenez null, si l'un d'eux n'est pas nul, les deux ne sont pas nuls, vous obtenez le meilleur.
C'est fou, surtout si vous allez l'utiliser plusieurs fois, alors vous voudrez peut-être le créer comme une fonction, comme ceci:
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 ;
Ensuite, vous pouvez l'utiliser comme ça
select cp_greatest_date(current_timestamp, null);
-- output is 2017-05-05 20:22:45