1
votes

Comment obtenir la première valeur non NULL en SQL?

J'ai trois colonnes de données. Une colonne a un ID et la deuxième colonne a une date et la troisième colonne a une valeur IMC. Je veux créer une quatrième colonne dont la valeur first_value est basée sur la date (ordre croissant) de la troisième colonne qui n'est pas nulle ou qui évite la valeur nulle.

Jusqu'à présent, j'ai essayé first_value sous forme simple qui n'a pas fonctionné. J'ai essayé de sous-définir first_value dans le cas lorsque l'instruction comme

id    date         BMI 
1   2000-01-01    NULL
1   2003-05-01    18.1
1   2002-07-15    25.8
2   2009-09-25    NULL
2   2015-04-18    23.5

m'a donné des 0.

CASE 
  WHEN BMI IS NOT NULL THEN (FIRST_VALUE(BMI) OVER PARTITION BY PID ORDER BY DATE)) 
  ELSE 0 
END AS FIRSTNOTNULLVALUE_BMI

Des suggestions ??


6 commentaires

Affichez des échantillons de données et les résultats attendus pour clarifier.


Veuillez marquer votre question avec la base de données que vous utilisez: mysql, sql-server, postgresql ...?


a publié un exemple de données et ajouté des balises pour les bases de données.


Vos exemples de données ne contiennent aucune valeur nulle dans l'IMC. Publiez des exemples de données avec des résultats nuls et attendus .


De plus, Mysql n'est pas le même que SQLite. Marquez uniquement la base de données que vous utilisez.


Vous avez oublié les résultats attendus.


4 Réponses :


0
votes

Je pense que vous pouvez faire quelque chose comme ça .. peut-être fonctionnera .. ou vous donnera une idée

   THEN (select BIM = row_number() over (partition by BIM order by DATE desc/asc) 
      from Products)
ELSE..


0 commentaires

1
votes

Vous pouvez joindre votre table avec une sous-requête qui récupère le premier IMC non nul, par date:

select
    t.*,
    x.bmi first_non_null_bmi
from mytable t
cross join (select bmi from mytable where bmi is not null order by date limit 1) x


0 commentaires

1
votes

Vous pouvez mettre ce CASE dans le ORDER BY de la FIRST_VALUE .
Ensuite, les valeurs nulles seront triées en dernier pour cette fonction.

pid | pdate      | BMI  | firstBMI
:-- | :--------- | :--- | :-------
1   | 2000-01-01 | null | 24.9    
1   | 2002-07-15 | 24.9 | 24.9    
1   | 2003-05-01 | 18.5 | 24.9    
2   | 2009-09-25 | null | 21.7    
2   | 2015-04-18 | 21.7 | 21.7    
select *
, first_value(BMI) over (partition by pid order by case when BMI is not null then 1 else 2 end, date(pdate)) as firstBMI
from test
order by pid, pdate
create table test
(
  pid int,
  pdate date,
  BMI decimal(4,1)
)

insert into test (pid, pdate, BMI) values
  (1, '2000-01-01', NULL)
, (1, '2003-05-01', 18.5)
, (1, '2002-07-15', 24.9)
, (2, '2009-09-25', NULL)
, (2, '2015-04-18', 21.7)
;

db fiddle ici em>


2 commentaires

Merci beaucoup! Vous m'avez guidé dans la bonne direction. J'ai édité le code ci-dessus comme select *, first_value (bmi) over (partition par pid ordre par cas lorsque bmi est nul puis 1 else 0 end) comme firstnonnull_bmi à partir de vitals_f2 order by pid;


@PrajwalManiPradhan Thx, j'ai corrigé la réponse. Btw, seule une commande par CASE ne suffit pas pour obtenir le plus ancien IMC non nul



0
votes

Vous pouvez simplement utiliser une sous-requête:

select bmi.*,
       (select bmi2.bmi
        from bmi bmi2
        where bmi2.id = bmi.id and bmi2.bmi is not null
        order by bmi2.date
        limit 1
       ) as first_bmi
from bmi;


0 commentaires