这些SQL语句是否相同?

时间:2016-07-24 13:01:46

标签: mysql sql

我有下表:

| 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之后的查询)?

3 个答案:

答案 0 :(得分:1)

[这是问题的原始版本]

完全没有。 != NULL会过滤掉所有数据,因为几乎所有与NULL的比较都会返回NULL,这会被视为错误。

!= ''将返回所有不包含空字符串且不是NULL的值。

NULL的正确比较使用is nullis 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的结果。