2016-07-24 66 views
0

我有以下表:这些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 

我通过重写查询作为以为优化代码:基于一些文档我读here

SELECT sample_id, field1, field2 
FROM  samples 
WHERE field1 != NULL 
OR  field2 != NULL 
ORDER BY RAND() 
LIMIT 1000 

似乎都查询是等效的,但我不知道如何在查询中处理ORDER BY RAND()行。它仅适用于第二个查询(即UNION ALL之后的查询)吗?

回答

1

[这是问题的原始版本]

不是。 != NULL将过滤掉所有数据,因为几乎所有与NULL的比较都返回NULL,将其视为false。

!= ''将返回所有不包含空字符串且不是NULL的值。使用is nullis not null

[AFTER编辑] 你想查询的是:

所有的
SELECT sample_id, field1, field2 
FROM samples 
WHERE field1 IS NOT NULL OR field2 IS NOT NULL 
ORDER BY RAND() 
LIMIT 1000; 
+0

原始查询中的ORDER_BY RAND()行只应用于第二个select语句还是两者? –

+0

@SyafiqKamarulAzman。 。 。如在原始查询中一样,它适用于两者。这就是原始查询的工作原理,所以应该是答案的作用。 –

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都为null,如果存在,将由UNION ALL选择两次,并且选择的概率为

因此,在这两种情况下,您最多可以获得1000条记录,但这两组数据会略有不同。

很可能您的优化查询一旦更新为IS NOT NULL而不是!=就是您从一开始就需要的实际查询。

但是,如果你做希望双概率双归零行,那么优化的查询将等价的,如果你在一些随机过程使用这些数据作为输入它可能会扭曲的结果。

+0

由于我不想要双重概率,这是否意味着我的优化是一个更好的查询? –

+0

是的,只要你得到适当的检查(IS NOT NULL)。 – LSerni

0

将order by应用于union的结果。