0
votes

Comment écrire des sous-requêtes dans le cas dans MySql?

J'ai une table qui ressemble à ceci

estimatedunits
9
0
9
3

Je veux un résultat où si jjsc_from_status = 'E' alors vérifier si le même travail lorsque jjsc_from_status = 'D' avait un autre jjsc_wf_userid . Si c'est le cas, renvoyez 3 sinon 0

J'ai écrit quelque chose comme ça mais dit erreur de syntaxe

select case jjsc_from_status 
                    when 'E' then if(select jjsc_from_status from jdwf_job_status_cycle where jjsc_wf_userid = jjsc_wf_userid, 0,3 )
                    when 'D' then 9                     
                    end as estimatedunits
                    from jdwf_job_status_cycle 
                    where jjsc_time>='$fDate' and jjsc_time<='$tDate'
                    order by jjsc_time

Le résultat attendu est

jjsc_job_no jjsc_from_status jjsc_time           jjsc_wf_userid
123456      D                2012-07-01 13:33:27 804
123456      E                2014-04-08 03:22:35 804
123457      D                2012-07-01 13:33:27 805
123457      E                2014-04-08 03:22:35 806


0 commentaires

3 Réponses :


1
votes

Vous pouvez le faire avec un CASE imbriqué et EXISTS:

| estimatedunits |
| -------------- |
| 9              |
| 0              |
| 9              |
| 3              |

Voir le demo (sans la clause WHERE).
Résultats:

select 
  case j.jjsc_from_status 
    when 'D' then 9
    when 'E' then 
      case 
        when exists (
          select 1 from jdwf_job_status_cycle 
          where jjsc_job_no = j.jjsc_job_no and jjsc_from_status = 'D' 
          and jjsc_wf_userid <> j.jjsc_wf_userid)
        then 3 
        else 0 
      end 
  end as estimatedunits
from jdwf_job_status_cycle j 
where jjsc_time>='$fDate' and jjsc_time<='$tDate'
order by jjsc_time


0 commentaires

1
votes

Vous devez TOUJOURS utiliser des alias pour vos tables!

Dans ce cas, vous souhaitez utiliser les données de la table des lecteurs dans la sous-requête, mettez donc 2 alias différents pour eux:

select 
    case jsc.jjsc_from_status 
        when 'E' then if(exists(select jjsc_from_status from jdwf_job_status_cycle jsc2 where jsc2.jjsc_job_no = jsc.jjsc_job_no and jsc2.jjsc_from_status = 'D' and jsc2.jjsc_wf_userid <> jsc.jjsc_wf_userid), 3, 0)
        when 'D' then 9
    end as estimatedunits
from jdwf_job_status_cycle jsc
where jsc.jjsc_time>='$fDate' and jsc.jjsc_time<='$tDate'
order by jsc.jjsc_time


0 commentaires

0
votes

La cause de l'erreur de syntaxe est de placer select qui renvoie une chaîne dans la clause if , vous devez modifier la requête dans la clause if en renvoie un résultat booléen, quelque chose comme:

select case jjsc_from_status 
                    when 'E' then if( (select count(jjsc_from_status) from jdwf_job_status_cycle as t2 where t1.jjsc_wf_userid = t2.jjsc_wf_userid) > 0, 0,3 )
                    when 'D' then 9                     
                    end as estimatedunits
                    from jdwf_job_status_cycle as t1
                    where jjsc_time>='$fDate' and jjsc_time<='$tDate'
                    order by jjsc_time


2 commentaires

encore ce serait ambigu: jjsc_wf_userid = jjsc_wf_userid


vous avez raison, sémantiquement c'est faux, mais du point de vue syntaxique, cette condition est correcte, et elle sera toujours vraie lorsqu'elle compare les deux valeurs de la requête de sous-sélection. J'ai mis à jour la requête pour inclure également les alias