具有复杂查询的WHERE子句中的MySQL Query Precedence

时间:2014-05-30 14:39:50

标签: mysql

我正在努力实现以下目标。

我必须从我的数据库中获取所有已付款,仍可使用(未过期)但尚未使用的优惠券代码。

这是我写的查询:

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))

我最大的疑问是关于最后几行:

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))

事实上,我的数据库中有两种可能的交易。一种类型在特定日期显示,另一种类型仅在用户购买优惠券后N天过期。

现在如果我这样做,我得到2900个结果:

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))

如果我这样做,我会得到6000个结果(注意下面的一个中有一个较少的括号):

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)

我需要获得这两种类型,但由于某些原因,更改优先级会更改结果的数量。这对我来说没有意义,因为在我看来它应该是完全相同的结果。

1 个答案:

答案 0 :(得分:0)

只要我能看到没有测试,最后一个查询条件是错误的。如果从左到右计算括号,则表示当到达OR时,没有打开的。因此,或者在与IN条款相同的级别进行评估,并且IN条款会给您带来意想不到的结果。这个上面的条件看起来很好。