我在这里有3个查询有什么区别?
第一个版本适用于我的localhost xampp mysql数据库(10.1.9-MariaDB)。但是,它使用我的在线测试服务器mysql数据库(5.7.9-log MySQL社区服务器GPL)检索0结果。
第二个版本检索两个服务器的预期结果。但是在我的localhost查询2中检索相同的结果集,虽然顺序不同,但是我猜这是因为我没有订单。
这是不同版本的mysql的问题吗?如何,如果我的查询不同?
查询1
TC_char_profiles
QUERY2
SELECT
s.eid, e.fname, e.lname, s.id, s.starttime, s.finishtime
FROM
employees AS e
RIGHT JOIN
scheduling_shifts AS s USING (eid)
GROUP BY s.id
HAVING COUNT(s.date = '2016-01-15' OR NULL) > 0
AND COUNT(s.eid = '1' OR NULL) = 0;
EDIT :: 的 QUERY3
此查询还检索正确的结果集减去NULL SELECT
s.eid, e.fname, e.lname, s.id, s.starttime, s.finishtime
FROM
employees AS e
RIGHT JOIN
scheduling_shifts AS s USING (eid)
WHERE
s.date = '2016-01-15'
GROUP BY s.id
HAVING COUNT(s.eid = '1' OR NULL) = 0;
s.eid
编辑::以下是我自己在SQLfiddle
上查询的测试用例目标是在所选日期获取所选员工的可能互换列表。我们选择的日期是 SELECT
s.eid, e.fname, e.lname, s.id, s.starttime, s.finishtime
FROM
employees AS e
RIGHT JOIN
scheduling_shifts AS s USING (eid)
WHERE
s.date = '2016-01-15' AND s.eid <> '1'
,我们想要换班的选定员工是员工15th Jan 2016
。该列表无法取得自己的转变,因为他无法与自己交换班次。但它应该带来未分配的转变。 (1
为eid
)的位移。因此,该选项会显示其他员工及其轮班的列表,或者在这一天我们可以与我们交换的未分配班次。
请注意查询1 - 确实会在此生成正确的结果,执行会在xampp(mariadb 10)上生成正确的结果,但没有在我的在线测试服务器上。
查询2 也会获取正确的结果,同时也会执行xampp和在线测试服务器。
查询3 会抓取所有已分配的班次,但不会取消未分配的班次。
希望这能更好地解释我的问题。
答案 0 :(得分:2)
WHERE
子句考虑每行的条件,HAVING
子句考虑聚合,但我不认为这是差异的原因。
你使用&#34; OR NULL&#34;是误导性的,并且会在某些时候(如果不是现在)产生意外或不正确的结果,请注意,当表达式为NON-NULL 时, COUNT()仅递增。 / p>
下面,使用MySQL 5.6 at SQL Fiddle,我尝试显示效果: 查询1 : <强> Results 强>: 查询2 : <强> Results 强>: 在上面的Query1中,您可以看到&#34; OR NULL&#34;不计算但在我的Query2中,表达式对所有行都返回true,因此所有行都被计算在内。 &#34; OR NULL&#34;是一个常量NULL,并且COUNT()不会为NULL增加 [编辑]
我建议您使用CREATE TABLE Table1
(`ID` int, `Other` varchar(4))
;
INSERT INTO Table1
(`ID`, `Other`)
VALUES
(1, 'ABC'),
(2, 'DEF'),
(3, NULL)
;
SELECT COUNT(`other` > '0' OR NULL)
FROM Table1
| COUNT(OTHER > '0' OR NULL) |
|----------------------------|
| 2 |
SELECT COUNT(`other` > '0' OR `other` IS NULL)
FROM Table1
| COUNT(`other` > '0' OR `other` IS NULL) |
|-----------------------------------------|
| 3 |
COUNT(*)
,因为看起来您想要做的就是计算每一行,这正是COUNT(*)
无法访问每一列的所有内容,它所关心的只是&#39 ;行是否存在&#39;。
通过&lt;&gt;比较NULL (不相等)不起作用。 NULL不能等于任何东西,因此也不可能知道它是否相等(因为你必须知道它是is equal
之前它is not equal
)
在y&amp;列中查看关节z在以下结果中:
SELECT
COUNT(OTHER > '0' OR NULL) orig
, COUNT(`other` > '0' OR `other` IS NULL) x
, count(case when `other` <> 'abc' then NULL else 1 end) y
, count(case when `other` <> 'abc' or `other` is null then NULL else 1 end) z
FROM Table1
<强> Results 强>:
| orig | x | y | z |
|------|---|---|---|
| 2 | 3 | 2 | 1 |
作为一个sqlfiddle测试用例,我将如何构建查询。它列出了提供的表scheduling_shifts中的9行中的8行:
SELECT
s.eid, e.fname, e.lname, s.id, s.date, s.starttime, s.finishtime
FROM scheduling_shifts s
LEFT JOIN employees AS e on s.eid = e.eid
WHERE (s.eid <> 1 OR s.eid is null)
AND s.date = '2016-01-15';
由于我无法重现您的具体问题(来自不同平台的不同结果),我遗憾地说只有您使用&#34;或NULL&#34;让我感到不寻常,并可能产生不可预测的结果。作为查询的第二个特性,当你没有特别的理由时,你正在使用having子句,我也会避免这样做。