简体   繁体   中英

MySQL Query Precedence in WHERE clause with complex query

I am trying to achieve the following.

I have to get all the coupon codes from my DB that are paid, still usable (not expired) but not used yet.

This is the query I wrote:

SELECT o.offer_id Offerta
     , c.payment_id Transazione
     , c.coupon Coupon
     , c.status Stato
     , p.total_paid Netto
     , p.total_paid_nocred Lordo
FROM `coupons` c
     LEFT JOIN offers o ON c.offer_id=o.offer_id
     LEFT JOIN payments p ON c.payment_id=p.payment_id 
     LEFT JOIN offers_categories cat ON o.offer_id=cat.offer_id
WHERE c.status = 1
    AND usage_date = 0 
    AND p.status IN (0,1) 
    AND cat.category_id IN(4,16,134,13,17,61,62,63,64,14,15,31,124,125,126)
    AND ((o.coupon_validto > UNIX_TIMESTAMP(NOW())
    AND o.instant_coupon != 1) OR (o.instant_ends_30days > DATEDIFF(NOW(), FROM_UNIXTIME(p.time)) AND instant_coupon = 1))

My big doubt is regarding the last few lines:

AND ((o.coupon_validto > UNIX_TIMESTAMP(NOW())
AND o.instant_coupon != 1) OR (o.instant_ends_30days > DATEDIFF(NOW(), FROM_UNIXTIME(p.time)) AND instant_coupon = 1))

In fact I have two types of possible deals in my DB. One type dues in a specific date and another type dues only once N days have passed from when the user bought the coupon.

Now if I do this way I get 2900 results:

AND ((o.coupon_validto > UNIX_TIMESTAMP(NOW())
AND o.instant_coupon != 1) OR (o.instant_ends_30days > DATEDIFF(NOW(), FROM_UNIXTIME(p.time)) AND instant_coupon = 1))

If I do this way I get like 6000 results (note there is one less parenthesis in the below one):

AND (o.coupon_validto > UNIX_TIMESTAMP(NOW())
AND o.instant_coupon != 1) OR (o.instant_ends_30days > DATEDIFF(NOW(), FROM_UNIXTIME(p.time)) AND instant_coupon = 1)

I need to get both types, but for some reasons changing the precedence changes the number of results. It does not make sense to me because it should be the very same result in my opinion.

As long as i can see without test, the last query condition is wrong. If you count parenthesis from left to right turns out that when you reach the OR, there is no open one. So the or is evaluated at the same level as the firt AND ant the IN clause giving you unexpected results. The condition above this one looks fine.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM