我的表格“用户”和“作业”以及以下数据
USERS
+------+---------------+-----------+---------+---------------------+
| id | first_name | last_name | role_id | created |
+------+---------------+-----------+---------+---------------------+
| 1026 | Administrator | Larvol | 2 | 2014-07-25 22:28:21 |
| 20 | Worker | Larvol | 3 | 2014-07-24 20:14:18 |
| 22 | test | user | 3 | 2014-07-25 16:06:27 |
+------+---------------+-----------+---------+---------------------+
工作
+----+--------+---------+
| id | status | user_id |
+----+--------+---------+
| 1 | 3 | 20 |
| 2 | 4 | 22 |
+----+--------+---------+
到目前为止,我从表中获取数据的工作是
SELECT Worker.id,
first_name,
last_name,
role_id,
Worker.created,
(COUNT( NULLIF(Job.id, 0) )) AS JobsAmount,
((SUM( IF( status <> 0, 1, 0 ) )-SUM( IF( status = 1, 1, 0 ) ))) AS JobsReviewed
FROM alpha_dev.users AS Worker LEFT JOIN jobs AS Job ON Job.user_id = Worker.id
WHERE Worker.role_id = 3
GROUP BY Worker.id;
我得到的结果是
+----+------------+-----------+---------+---------------------+------------+--------------+
| id | first_name | last_name | role_id | created | JobsAmount | JobsReviewed |
+----+------------+-----------+---------+---------------------+------------+--------------+
| 20 | Worker | Larvol | 3 | 2014-07-24 20:14:18 | 1 | 1 |
| 22 | test | user | 3 | 2014-07-25 16:06:27 | 1 | 1 |
+----+------------+-----------+---------+---------------------+------------+--------------+
现在我想在上创建OR条件(COUNT(NULLIF(Job.id,0)))AS JobsAmount,“类似
WHERE Worker.role_id = 3 OR (COUNT( NULLIF(Job.id, 0) )) = 1
但这不起作用,所以我最终得到了HAVING子句
WHERE Worker.role_id = 3
GROUP BY Worker.id
HAVING COUNT(NULLIF(`Job`.`id`, 0)) = 0;
HAVING在这里作为AND条件。并且给了我EMPTY SET,而我希望HAVING中的条件作为OR条件工作,所以
Worker.role_id = 3 OR COUNT(NULLIF(`Job`.`id`, 0)) = 0
应该是真的让事情完成。
任何帮助将不胜感激。谢谢
答案 0 :(得分:1)
COUNT是一个聚合函数。因此,如果不对某些内容进行分组,那么它并不意味着任何事情。如果你想要那些条件的OR,那么解决方案可能是两个查询的并集,一方面查询没有,只有role_id = 3条件,另一方面查询具有COUNT条件和role_id不相等到3。
SELECT Worker.id,
first_name,
last_name,
role_id,
Worker.created,
(COUNT( NULLIF(Job.id, 0) )) AS JobsAmount,
((SUM( IF( status <> 0, 1, 0 ) )-SUM( IF( status = 1, 1, 0 ) ))) AS JobsReviewed
FROM alpha_dev.users AS Worker LEFT JOIN jobs AS Job ON Job.user_id = Worker.id
WHERE Worker.role_id = 3
GROUP BY Worker.id
UNION
SELECT Worker.id,
first_name,
last_name,
role_id,
Worker.created,
(COUNT( NULLIF(Job.id, 0) )) AS JobsAmount,
((SUM( IF( status <> 0, 1, 0 ) )-SUM( IF( status = 1, 1, 0 ) ))) AS JobsReviewed
FROM alpha_dev.users AS Worker LEFT JOIN jobs AS Job ON Job.user_id = Worker.id
WHERE Worker.role_id <> 3
GROUP BY Worker.id
HAVING COUNT(NULLIF(`Job`.`id`, 0)) = 0;
可能使用UNION ALL而不是UNION,它具有更好的性能,但这取决于您是否希望或因为联合而有重复的行。
答案 1 :(得分:1)
如果COUNT(NULLIF(Job.id, 0))
中没有关联的行,则表达式Job
将为零。
检查Job
中是否存在关联行的另一种方法是查看Job
中的必填列是否为空。我说必需列,因为无论如何可选列都可以为null,而如果左连接表中没有任何匹配项,则必需列将只为null。
更具体地说,在特定情况下,我非常确定COUNT(NULLIF(Job.id, 0))
与Job.user_id IS NULL
的条件相同。由于表达式Job.user_id IS NULL
不是基于聚合,因此它可以进入WHERE
而不是HAVING
:
role = 3 OR job count = 0
SELECT Worker.id,
first_name,
last_name,
role_id,
Worker.created,
(COUNT( NULLIF(Job.id, 0) )) AS JobsAmount,
((SUM( IF( status <> 0, 1, 0 ))-SUM( IF( status = 1, 1, 0 ) ))) AS JobsReviewed
FROM alpha_dev.users AS Worker
LEFT JOIN jobs AS Job ON Job.user_id = Worker.id
WHERE Worker.role_id = 3 OR Job.user_id IS NULL
GROUP BY Worker.id
这仅适用于COUNT = 0。如果您需要检查COUNT = 2或COUNT = 5或其他什么,您需要将现有查询推送到子查询中,然后让外部查询应用OR
逻辑:
role = 3 OR job count = 5
SELECT * FROM (
SELECT Worker.id,
first_name,
last_name,
role_id,
Worker.created,
(COUNT( NULLIF(Job.id, 0) )) AS JobsAmount,
((SUM(IF(status <> 0, 1, 0))-SUM( IF(status = 1, 1, 0)))) AS JobsReviewed
FROM alpha_dev.users AS Worker
LEFT JOIN jobs AS Job ON Job.user_id = Worker.id
GROUP BY Worker.id
) WorkerSummary
WHERE role_id = 3 OR JobsAmount = 5
答案 2 :(得分:1)
我不知道它是否正确,但我遵循了一个技巧。而不是在where子句中写条件。我也写了条件 它工作得很好......所以我想问一下#34;这样构造查询是否会产生任何影响&#34;或任何性能问题?? 请提供宝贵的反馈..... SELECT Worker.id,
first_name,
last_name,
role_id,
Worker.created,
(COUNT( NULLIF(Job.id, 0) )) AS JobsAmount,
((SUM(IF(status <> 0, 1, 0))-SUM(IF(status = 1, 1, 0)))) AS JobsReviewed
FROM alpha_dev.users AS Worker
LEFT JOIN jobs AS Job
ON Job.user_id = Worker.id
GROUP BY Worker.id
HAVING role_id = 3 OR JobsAmount = 5;