我编写了一个SQL查询来查找连续出现至少三次的所有数字:
| Id |的 货号 |
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 1 |
| 6 | 2 |
| 7 | 2 |
例如,鉴于上述 日志 表, 1 是连续出现的唯一数字至少三次。
我的原始查询返回1和2:
SELECT l1.Num
FROM Logs l1, Logs l2, Logs l3
WHERE l1.Id + 2 = l2.Id + 1 = l3.Id
AND l1.Num = l2.Num = l3.Num;
+ ---------------------------------------------- --------------------------
然后我将查询更改为此(基本上我将a + 2 = b + 1 = c更改为+ 1 = b和b + 1 = c),它会返回正确的答案:
SELECT l1.Num
FROM Logs l1, Logs l2, Logs l3
WHERE l1.Id + 1 = l2.Id AND l2.Id + 1 = l3.Id
AND l1.Num = l2.Num AND l1.Num= l3.Num;
+ ---------------------------------------------- --------------------------
它让我发疯,我无法理解为什么。有人可以向我解释这个吗?在此先感谢!!!!答案 0 :(得分:0)
好吧,让我们来看看这个查询:
WHERE l1.Id + 2 = l2.Id + 1 = l3.Id
在MySQL和大多数编程语言中,=
只是一个二元运算符,这意味着它需要左侧和右侧,如果相同则返回true,否则返回false。
在您的查询中,您首先将l1.Id + 1
与l2.Id
进行比较,从而产生真值。然后,将真值与l3.Id
进行比较。 (真值将自动转换为0
/ 1
)。这导致不同的结果。
tl; dr:=
与数学符号中经常使用的=
不同。
答案 1 :(得分:0)
当你使用多个=
运算符(即链接)时,MySQL会从左到右对其进行评估,然后将最左边的比较结果送到下一个操作。看一下 SQL Fiddle :
id=id=2
返回false,因为id=id
返回1和1 != 2
。
现在,就查询而言,我认为使用SELECT
中的变量有一种更简单的方法。根据您的方法,如果我们要找到4次出现的所有数字,那么我们需要再做一次连接。相反,我们可以这样做:
SELECT id, num,
@counter := IF(@previousNum = num, @Counter + 1, 1) AS counter,
@previousNum := num as prevNum
FROM test, (select @counter := 1, @previousNum := -1) a
ORDER BY id;
这将返回id和值以及计数器,如果连续的id具有相同的num
值,则会递增。
现在,如果我们想要过滤掉超过3次出现的值,我们需要将此查询包装在另一个select语句中,例如:
SELECT id
FROM
(SELECT id, num,
@counter := IF(@previousNum = num, @Counter + 1, 1) AS counter,
@previousNum := num as prevNum
FROM test, (select @counter := 1, @previousNum := -1) a
ORDER BY id) a
WHERE a.counter >= 3;
以下是 SQL Fiddle 。您可以轻松更改计数器值,以查找不同数量的连续外观的值。