我有下表:
| sample_id (varchar, unique) | field1 (int) | field2 (int) | ...
--------------------------------------------------------------------
| 9b7acb476c4ab04c7ddbc | 100 | 56 | ...
| a2e4df67e98ccaf088abf | 23 | NULL | ...
| fcbe9cecd6b96cba7c6ee | NULL | 43 | ...
...
我有一个先前用户创建的以下代码,可以同时查询两个字段并获取行的随机子集:
SELECT sample_id, field1, field2
FROM samples
WHERE field1 != NULL
UNION ALL
SELECT sample_id, field1, field2
FROM samples
WHERE field2 != NULL
ORDER BY RAND()
LIMIT 1000
我想通过将查询重写为:
来优化代码SELECT sample_id, field1, field2
FROM samples
WHERE field1 != NULL
OR field2 != NULL
ORDER BY RAND()
LIMIT 1000
根据我阅读here的一些文档,似乎两个查询都是等价的,但我不确定如何在查询中处理ORDER BY RAND()
行。它是否仅应用于第二个查询(即UNION ALL
之后的查询)?
答案 0 :(得分:1)
[这是问题的原始版本]
完全没有。 != NULL
会过滤掉所有数据,因为几乎所有与NULL
的比较都会返回NULL
,这会被视为错误。
!= ''
将返回所有不包含空字符串且不是NULL
的值。
与NULL
的正确比较使用is null
和is not null
。
[编辑后] 您想要的查询是:
SELECT sample_id, field1, field2
FROM samples
WHERE field1 IS NOT NULL OR field2 IS NOT NULL
ORDER BY RAND()
LIMIT 1000;
答案 1 :(得分:0)
首先,您的查询目前无效。它们都选择使用假的条件,因为所有的NULL比较都是:
mysql> select '' != NULL, NULL != NULL, 0 != NULL, 'hello' != NULL, 42 != NULL, (1=0)!=NULL, (1=1)!=NULL;
+------------+--------------+-----------+-----------------+------------+-------------+-------------+
| '' != NULL | NULL != NULL | 0 != NULL | 'hello' != NULL | 42 != NULL | (1=0)!=NULL | (1=1)!=NULL |
+------------+--------------+-----------+-----------------+------------+-------------+-------------+
| NULL | NULL | NULL | NULL | NULL | NULL | NULL |
+------------+--------------+-----------+-----------------+------------+-------------+-------------+
1 row in set (0.00 sec)
select 1 from test where null;
Empty set (0.00 sec)
现在,如果你使用不同的条件,例如WHERE field1 IS NOT NULL
,查询可能仍然微不相同。
第一个更新的UNIONed子查询现在将返回field1不为null的行。这将由field2不为空的行补充。
UNION ALL禁止重复。
field1和field2都为空的行(如果存在)将由UNION ALL选择两次,并且具有被选中的双倍概率。
因此,在这两种情况下,您最多可获得1000条记录,但这两组将略有不同。
很可能您的优化查询一旦使用IS NOT NULL而不是!=更新,就是您从一开始就需要的实际查询。
但是如果你做想要双重概率的双重概率,那么优化的查询将不相等,如果你将这些数据用作在一些随机过程中输入。
答案 2 :(得分:0)
order by应用于union的结果。