web-dev-qa-db-fra.com

Est-il possible pour une requête mysql de renvoyer true/false au lieu de valeurs?

J'ai une table:

custID    orderID    orderComponent
=====================================
1          123        pizza
1          123        wings
1          234        breadsticks
1          239        salad
2          456        pizza
2          890        salad

J'ai une liste de valeurs - pizza, ailes, gressins et salade. J'ai besoin d'un moyen d'obtenir simplement une valeur vrai/faux si un client a au moins un enregistrement contenant chacun de ceux-ci. Est-ce possible avec une requête mysql, ou dois-je simplement faire une select distinct(orderComponent) pour chaque utilisateur et utiliser php pour vérifier les résultats?

11
EmmyS

Si vous souhaitez simplement savoir si le client a commandé tous les articles, vous pouvez utiliser:

select t1.custid,
  case when t2.total is not null 
    then 'true'
    else 'false'
  end OrderedAll
from yourtable t1
left join
(
  select custid, count(distinct orderComponent) Total
  from yourtable
  where orderComponent in ('pizza', 'wings', 'breadsticks', 'salad')
  group by custid
  having count(distinct orderComponent) = 4
) t2
  on t1.custid = t2.custid

Voir SQL Fiddle avec démonstration

Si vous voulez développer ceci, pour voir si la custid a commandé tous les articles en une seule commande, alors vous pouvez utiliser:

select t1.custid,
  t1.orderid,
  case when t2.total is not null 
    then 'true'
    else 'false'
  end OrderedAll
from yourtable t1
left join
(
  select custid, orderid, count(distinct orderComponent) Total
  from yourtable
  where orderComponent in ('pizza', 'wings', 'breadsticks', 'salad')
  group by custid, orderID
  having count(distinct orderComponent) = 4
) t2
  on t1.custid = t2.custid
  and t1.orderId = t2.orderid

Voir SQL Fiddle avec démonstration

Si vous souhaitez uniquement les valeurs custid et true/false, vous pouvez ajouter distinct à la requête.

select distinct t1.custid,
  case when t2.total is not null 
    then 'true'
    else 'false'
  end OrderedAll
from yourtable t1
left join
(
  select custid, count(distinct orderComponent) Total
  from yourtable
  where orderComponent in ('pizza', 'wings', 'breadsticks', 'salad')
  group by custid
  having count(distinct orderComponent) = 4
) t2
  on t1.custid = t2.custid

Voir SQL Fiddle avec démonstration

Ou par custid et orderid:

select distinct 
  t1.custid,
  t1.orderid,
  case when t2.total is not null 
    then 'true'
    else 'false'
  end OrderedAll
from yourtable t1
left join
(
  select custid, orderid, count(distinct orderComponent) Total
  from yourtable
  where orderComponent in ('pizza', 'wings', 'breadsticks', 'salad')
  group by custid, orderID
  having count(distinct orderComponent) = 4
) t2
  on t1.custid = t2.custid
  and t1.orderId = t2.orderid

Voir SQL Fiddle avec démonstration

11
Taryn
select case when 
count(distinct orderComponent) = 4 
then 'true' 
else 'false' 
end as bool
from tbl
where custID=1
2
triclosan

Voici une approche. Cette approche ne nécessite pas de vue en ligne (table dérivée) et peut être efficace si vous souhaitez inclure des indicateurs pour plusieurs conditions:

MODIFIER:

Ceci retourne custID qui a une ligne pour les quatre éléments:

SELECT t.custID
     , MAX(IF(t.orderComponent='breadsticks',1,0))
       + MAX(IF(t.orderComponent='pizza',1,0))
       + MAX(IF(t.orderComponent='salad',1,0))
       + MAX(IF(t.orderComponent='wings',1,0)) AS has_all_four
  FROM mytable t
 GROUP BY t.custID
HAVING has_all_four = 4

RÉPONSE ORIGINALE:

(Ceci vérifiait la "commande" d'un client qui contenait les quatre articles plutôt qu'un "custID".)

SELECT t.custID
     , t.orderID
     , MAX(IF(t.orderComponent='breadsticks',1,0))
       + MAX(IF(t.orderComponent='pizza',1,0))
       + MAX(IF(t.orderComponent='salad',1,0))
       + MAX(IF(t.orderComponent='wings',1,0)) AS has_all_four
  -- , MAX(IF(t.orderComponent='breadsticks',1,0)) AS has_breadsticks
  -- , MAX(IF(t.orderComponent='pizza',1,0)) AS has_pizza
  -- , MAX(IF(t.orderComponent='salad',1,0)) AS has_salad
  -- , MAX(IF(t.orderComponent='wings',1,0)) AS has_wings
  FROM mytable t
 GROUP BY t.custID, t.orderID
HAVING has_all_four = 4

Cela permettra d'obtenir les "ordres" contenant les quatre éléments. Si vous souhaitez ne renvoyer que des valeurs pour custID, utilisez la requête ci-dessus en tant que vue intégrée (intégrez-la dans une autre requête).

SELECT s.custID
  FROM (
         SELECT t.custID
              , t.orderID
              , MAX(IF(t.orderComponent='breadsticks',1,0))
                + MAX(IF(t.orderComponent='pizza',1,0))
                + MAX(IF(t.orderComponent='salad',1,0))
                + MAX(IF(t.orderComponent='wings',1,0)) AS has_all_four
             FROM mytable t
            GROUP BY t.custID, t.orderID
           HAVING has_all_four = 4
       ) s
 GROUP BY s.custID
1
spencer7593

@EmmyS: vous pouvez le faire dans les deux sens. Si vous voulez vérifier avec MySql, utilisez:

SELECT @rowcount:=COUNT(*) FROM orderComponent Where (Your Conditions);
IF (@rowcount > 0) THEN
    'True'
ELSE
    'False'
END IF
0
Learner