简体   繁体   English

比较运算符在 MySQL 查询中不起作用

[英]Comparison operator is not working in MySQL query

i have this MySQL query:我有这个 MySQL 查询:

SELECT * FROM forex_pair_signals AS SENALES 
JOIN forex_pair_price AS PRECIO 
ON SENALES.forex_pair_price_id = PRECIO.forex_pair_price_id 
JOIN forex_pair AS PARES 
ON PRECIO.forex_pair_id = PARES.forex_pair_id
WHERE 
PRECIO.forex_pair_price_time >= '2019-02-01 00:00' AND
PRECIO.forex_pair_price_time <= '2019-02-07 01:00' AND 
TIME (PRECIO.forex_pair_price_time) BETWEEN '06:00' AND '13:00' AND 
PARES.forex_pair_id = 13 AND SENALES.forex_pair_signals_result = 1 AND
PRECIO.forex_pair_price_rsi >= '80.00' 
OR PRECIO.forex_pair_price_rsi <= '20.00' 
ORDER BY SENALES.forex_pair_signals_id DESC

This query works fine except when add the following filter:此查询工作正常,除非添加以下过滤器:

AND PRECIO.forex_pair_price_rsi >= '80.00' OR 
PRECIO.forex_pair_price_rsi <= '20.00'

The problem is that the last filter do ignores all other filters and the result is get all data that does comply with the last filter.问题是最后一个过滤器会忽略所有其他过滤器,结果是获取所有符合最后一个过滤器的数据。

AND is evaluated before OR because AND has a higher precedence. ANDOR之前进行评估,因为AND具有更高的优先级。 Use parentheses to override the operator precendence :使用括号覆盖运算符优先级

WHERE
    PRECIO.forex_pair_price_time >= '2019-02-01 00:00' AND
    PRECIO.forex_pair_price_time <= '2019-02-07 01:00' AND 
    TIME (PRECIO.forex_pair_price_time) BETWEEN '06:00' AND '13:00' AND 
    PARES.forex_pair_id = 13 AND SENALES.forex_pair_signals_result = 1 AND
    (
        PRECIO.forex_pair_price_rsi >= '80.00' 
        OR
        PRECIO.forex_pair_price_rsi <= '20.00'
    )

Or you could rewrite your condition so it's just one expression:或者你可以重写你的条件,所以它只是一个表达式:

    PRECIO.forex_pair_price_rsi not between '20.01' and '79.99'

Operator precedence When you use more than one logical operator in an expression, MySQL evaluates the OR operators after the AND operators.运算符优先级 在表达式中使用多个逻辑运算符时,MySQL 会在 AND 运算符之后计算 OR 运算符。 This is called operator precedence.这称为运算符优先级。 1 1

 SELECT true OR false AND false;

Result结果

true OR false AND false ----------------------- 1


 SELECT (true OR false) AND false;

Result结果

(true OR false) AND false ------------------------- 0

thus you need parantheses for such case因此,您需要在这种情况下使用括号

WHERE 
PRECIO.forex_pair_price_time >= '2019-02-01 00:00' AND
PRECIO.forex_pair_price_time <= '2019-02-07 01:00' AND 
TIME (PRECIO.forex_pair_price_time) BETWEEN '06:00' AND '13:00' AND 
PARES.forex_pair_id = 13 AND SENALES.forex_pair_signals_result = 1 AND
(
    PRECIO.forex_pair_price_rsi >= '80.00' OR
    PRECIO.forex_pair_price_rsi <= '20.00' 
)

You should use parenthesis while using OR function, as it corresponds to either one or two WHERE Clause defined within it by differentiating in brackets.使用 OR 函数时应该使用括号,因为它对应于其中定义的一个或两个 WHERE 子句,用括号区分。

SELECT * FROM forex_pair_signals AS SENALES 
JOIN forex_pair_price AS PRECIO 
ON SENALES.forex_pair_price_id = PRECIO.forex_pair_price_id 
JOIN forex_pair AS PARES 
ON PRECIO.forex_pair_id = PARES.forex_pair_id
WHERE 
PRECIO.forex_pair_price_time >= '2019-02-01 00:00' AND
PRECIO.forex_pair_price_time <= '2019-02-07 01:00' AND 
TIME (PRECIO.forex_pair_price_time) BETWEEN '06:00' AND '13:00' AND 
PARES.forex_pair_id = 13 AND SENALES.forex_pair_signals_result = 1 AND
(PRECIO.forex_pair_price_rsi >= '80.00' 
OR PRECIO.forex_pair_price_rsi <= '20.00') 
ORDER BY SENALES.forex_pair_signals_id DESC;

I think I would try to tidy up the query by consolidating the ranged logic in the WHERE clause.我想我会尝试通过合并 WHERE 子句中的范围逻辑来整理查询。

SELECT *
FROM forex_pair_signals AS senales
INNER JOIN forex_pair_price AS precio ON senales.forex_pair_price_id = precio.forex_pair_price_id 
INNER JOIN forex_pair AS pares ON precio.forex_pair_id = pares.forex_pair_id
WHERE pares.forex_pair_id = 13
  AND senales.forex_pair_signals_result = 1
  AND precio.forex_pair_price_time BETWEEN '2019-02-01 00:00' AND '2019-02-07 01:00' 
  AND precio.forex_pair_price_rsi NOT BETWEEN '20.00' AND '80.00'
  AND TIME(precio.forex_pair_price_time) BETWEEN '06:00' AND '13:00'
ORDER BY senales.forex_pair_signals_id DESC

Your final WHERE clause condition can be rewritten as NOT BETWEEN which totally avoids the issue.您的最终 WHERE 子句条件可以重写为NOT BETWEEN ,这完全避免了这个问题。

I also took the liberty to make your table aliases lowercase and I rearranged the WHERE clause conditions to position the simpler/lighter conditions first.我还冒昧地使您的表别名小写,并重新排列了 WHERE 子句条件以首先定位更简单/更轻的条件。

I think this query is much tidier now.我认为这个查询现在更整洁了。

(ps Try to avoid using * in your SELECT claues; you should only ask for data that you intend to use.) (ps 尽量避免在你的 SELECT 子句中使用* ;你应该只询问你打算使用的数据。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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