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

问题描述 投票:1回答:4

我有这个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

此查询工作正常,但添加以下过滤器除外:

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

问题是最后一个过滤器确实忽略了所有其他过滤器,结果是获取了所有与最后一个过滤器相符的数据。

mysql sql join
4个回答
5
投票

ANDOR之前进行求值,因为AND具有更高的优先级。使用括号覆盖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'
    )

或者您可以重写您的条件,所以它只是一个表达式:

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

2
投票

运算符优先级当您在一个表达式中使用多个逻辑运算符时,MySQL会在AND运算符之后计算OR运算符。这称为运算符优先级。1

SELECT true OR false AND false;

结果

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

SELECT (true OR false) AND false;

结果

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

因此您需要在这种情况下使用括号

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

1
投票

我想我将通过在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

您的最终WHERE子句条件可以重写为NOT BETWEEN,这完全可以避免该问题。

[我也冒昧地使您的表别名小写,并重新排列了WHERE子句条件,以首先将较简单/较轻的条件置于位置。

我认为此查询现在更加整洁。

(p.s。尽量避免在SELECT语句中使用*;您应该只索取要使用的数据。)


1
投票

您应该在使用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;
© www.soinside.com 2019 - 2024. All rights reserved.