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?
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
select case when
count(distinct orderComponent) = 4
then 'true'
else 'false'
end as bool
from tbl
where custID=1
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:
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
(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
@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