2010-11-17 11 views
2

J'ai une série de dates associées à un identifiant unique dans une table. Par exemple:SQL: date la plus proche de l'ensemble des champs de date

1 | 1999-04-01 | 0000-00-00 | 0000-00-00 | 0000-00-00 | 2008-12-01 | 
2 | 1999-04-06 | 2000-04-01 | 0000-00-00 | 0000-00-00 | 2010-04-03 | 
3 | 1999-01-09 | 0000-00-00 | 0000-00-00 | 0000-00-00 | 2007-09-03 | 
4 | 1999-01-01 | 0000-00-00 | 1997-01-01 | 0000-00-00 | 2002-01-04 | 

Est-il possible, pour sélectionner la première date à partir de la liste prédéfinie des champs DATE à l'aide d'une simple commande SQL?

Ainsi, le résultat attendu serait:

1 | 1999-04-01 
2 | 1999-04-06 
3 | 1998-01-09 
4 | 1997-01-01 

Je devine que ce n'est pas possible, mais je voulais demander et assurez-vous. Ma solution actuelle à l'esprit consiste à mettre toutes les dates dans une table temporaire, puis en utilisant que pour obtenir le MIN()

grâce

Edit: Le problème avec l'utilisation MOINS() comme indiqué est que le nouveau comportement est retourner NULL si l'une des colonnes est NULL. Dans une série de dates comme l'ensemble de données en question, n'importe quelle date peut être NULL. Je voudrais obtenir la première date réelle de l'ensemble des dates.

SOLUTION: Utilisé une combinaison de LEAST() et IF() afin de filtrer les dates NULL.

SELECT LEAST(IF(date1=0,NOW(),date1), IF(date2=0,NOW(),date2), [...]); 

Enseignements a) COALESCE ne traite pas 0000-00-00 comme date NULL, b) MOINS retournera 0000-00-00 comme la plus petite valeur - je suppose que cela est dû à la comparaison entier interne (?)

Répondre

3
select id, least(date_col_a, date_col_b, date_col_c) from table 

upd

select id, least (
    case when date_col_a = '0000-00-00' then now() + interval 100 year else date_col_a end, 
    case when date_col_b = '0000-00-00' then now() + interval 100 year else date_col_b end) from table 
+0

Merci pour votre suggestion - le problème avec le moins() est qu'il retourne NULL (dates) comme le 0000-00-00 minimum que je fais ne pas vouloir; Je veux la première date réelle définie dans l'une de ces colonnes. –

+0

J'ai mis à jour ma réponse. –

+0

Merci - J'ai utilisé une approche similaire en combinant les IF au lieu de CASE. SELECT LEAST (IF (date1 = 0, MAINTENANT(), date1), [...]). Les dates NULL peuvent être comparées avec '= 0'. –

0

fait, vous pouvez le faire comme ci-dessous ou en utilisant une grande structure case ... ou avec least(date1, date2, dateN) mais que nul pourrait être la valeur minimale ...

select rowid, min(date) 
    from 
     (select rowid, date1 from table 
     union all 
     select rowid, date2 from table 
     union all 
     select rowid, date3 from table 
     /* and so on */ 
     ) 
group by rowid; 

HTH

0
select 
    id, 
    least(coalesce(date1, '9999-12-31'), ....) 
from 
    table 
+0

Bonne idée mais '0000-00-00' n'est pas considéré comme une valeur NULL par COALESCE. Par exemple, SELECT ('0000-00-00', NOW()) retournera 0000-00-00 –

+0

Ensuite, ce n'est pas réellement 'null'. Utilisez 'case' au lieu de' coalesce'. – Donnie