我有一些服务器。他们中的一些人分配了ips。我想弄清楚有多少没有。显然有更多的服务器比分配了ips,但我的数据库告诉我没有服务器没有分配ips ...
我在这里结束了我的智慧。我的数据库是否以某种奇怪的方式被破坏了?
SELECT COUNT(*)
FROM server
...返回:
+----------+
| count(*) |
+----------+
| 23088 |
+----------+
1 row in set (0.00 sec)
此:
SELECT COUNT(*)
FROM server
WHERE server_id IN (SELECT DISTINCT(server_id)
FROM ips)
...返回:
+----------+
| count(*) |
+----------+
| 13811 |
+----------+
1 row in set (0.01 sec)
此:
SELECT COUNT(*)
FROM server
WHERE server_id NOT IN (SELECT DISTINCT(server_id)
FROM ips);
...返回:
+----------+
| count(*) |
+----------+
| 0 |
+----------+
1 row in set (0.02 sec)
结果已被编辑以保护有罪,但你明白了。
Check table
在这两个表上都返回ok。编辑:感谢您使用LEFT JOIN
的建议。这肯定证实问题是MySQL的错误。
mysql> SELECT count(s.server_id) FROM server s LEFT JOIN ips i on s.server_id = i.server_id WHERE i.server_id IS NULL;
+--------------------+
| count(s.server_id) |
+--------------------+
| 9277 |
+--------------------+
1 row in set (0.04 sec)
由于9277 + 13811 = 23088,这意味着所有没有ips的服务器+所有带有ips的服务器确实==所有服务器。
我计划在下周开始升级mysql服务器。请继续关注。
答案 0 :(得分:7)
什么版本的MySQL?似乎有一个错误< 5.0.25 / 5.1.12可能是罪魁祸首:
Bug #21282: NOT IN,超过1000条使用INDEX返回错误的结果:
在NOT中使用
SELECT ... WHERE some_field NOT IN (...)
然后使用1000或更多值 如果有一个INDEX / UNIQUE键,则部分原因导致服务器返回错误的结果 some_field。少于1000个标准正常工作。
答案 1 :(得分:6)
你的专栏中是否有空?
答案 2 :(得分:4)
server_id not in (ids)
与NULL
列不匹配,因此您只能获得非server_id
的服务器,而{NULL} ips
不在where server_id is null
中。您需要使用{{1}}代替。
答案 3 :(得分:2)
假设错误truppo found导致错误,您可以使用此解决方法:
select count(*)
from server s
left join ips i on i.server_id = s.server_id
where i.server_id is null
如果i.server_id is null
找不到匹配项(就像left join
中的所有列都会因此情况而产生i
),则null
为真。
答案 4 :(得分:1)
您是否有任何对于server_id具有NULL的记录?因为在这两种情况下它都会被排除在外。
答案 5 :(得分:1)
如果列中包含NULL,则在两种情况下它们都将计算为false。您得到的结果是in
+ not in
- nulls
答案 6 :(得分:0)
select count(*)
from server
where server_id not in (select distinct(server_id) from ips)
or server_id is NULL
答案 7 :(得分:0)
我认为IN和NOT IN会发生奇怪的事情。可能是一个错误或“已知限制”。
我建议首先尝试回答你的初始问题(没有ip的服务器),然后查看数据......也许这可以告诉你可能会发生什么。
所以这里有一些替代想法可以为您提供所需的信息:
SELECT server_id
FROM server
MINUS
SELECT server_id
FROM ips
或者
SELECT server_id
FROM server s LEFT JOIN ips i on s.server_id = i.server_id
WHERE i.server_id is null
如上所述,这可能会让您了解数据未被原始陈述“捕获”的原因。