我不确定我是否正确地表达了这个标题,但是现在就这样了。我有这两个表:
表:员工id Name groupId Status
1 John Smith 1 1
2 John Doe 1 1
3 Jane Smith 2 1
4 Jerry Smith 1 1
表:jobqueue
id job_id staff_id jobStatus
1 1 1 1
2 2 1 1
3 5 2 1
4 7 3 0
现在,我需要做的是找到分配给他的工作量最少的员工,我可以通过查询jobqueue表来完成。
SELECT min(cstaff),tmp.staff_id FROM (SELECT t.staff_id, count(staff_id) cstaff from jobqueue t join staff s on t.staff_id=s.id join group g on s.groupId=g.id where g.id=26 GROUP BY t.id ) tmp
这很好用,但问题是如果员工根本没有分配到任何工作,这个查询就不会得到它们,因为它只查询jobqueue表,那个特定的员工没有任何条目。我需要修改查询以包括员工表,如果员工没有在工作队伍中分配任何工作,那么我需要从员工表中获取员工详细信息。基本上,我需要为没有分配任何工作的团队找到工作人员,如果所有员工都被分配了工作,那么找到分配了最少工作量的员工。可以使用一些帮助。此外,标记为Yii,我想知道这是否适用于Yii活动记录。但我可以使用一个简单的SQL查询来处理Yii sql命令。
答案 0 :(得分:1)
不确定它是最佳查询,但它确实有效:
select d.groupId, d.name, (select count(*) from jobqueue as e where e.staff_id=d.id) as jobassigned
from staff as d
where d.id in (
select
(
select a.id
from staff as a
left outer join
jobqueue as b
on (a.id = b.staff_id)
where a.groupId = c.groupId
group by a.id
order by count(distinct job_id) asc
limit 1
) as notassigneduserid
from (
select distinct groupId from staff
) as c)
可能需要一些评论:
获取所有不同的groupId需要 c
查询 - 如果你有单独的表,你可以替换它
notassigneduserid
语句选择具有最少作业数的用户
d
查询以获取所有找到的“未分配用户”的实际用户名groupId并显示
以下是问题数据的结果:
Group Staff Jobs assigned
1 Jerry Smith 0
2 Jane Smith 1
答案 1 :(得分:1)
with
counts as (
select s.groupId
, s.id
, (select count(*) from jobqueue where staff_id = s.id) count
from staff s
group by s.id, s.groupId),
groups as (
select groupId, min(count) mincount
from counts
group by groupId)
select c.groupId, c.id, c.count
from counts c
join groups g on c.groupId = g.groupId
where c.count = g.mincount
此SQL将为您提供每组中具有最少作业数的所有员工。可能不止一个员工拥有相同的最低工作岗位数。方法是使用公用表表达式首先构建计数列表,然后检索每个组的最小计数。最后,我加入计数和组表,并检索每个组具有最小计数的人员。
我在SQL Server上对此进行了测试,但语法也适用于MySQL。根据您的数据我添加了:
id Name groupId Status
5 Bubba Jones 2 1
6 Bubba Smith 1 1
和
id job_id staff_id jobStatus
5 4 5 1
结果
group name count
1 Bubba Smith 0
1 Jerry Smith 0
2 Bubba Jones 1
2 Jane Smith 1
顺便说一下,我不会尝试用活动记录来做这件事,这太复杂了。
答案 2 :(得分:0)
正如Ilya Bursov所说,这个答案并没有完全回应所要求的。所以这是一个更优化的解决方案:
SELECT *
FROM (
SELECT s.id as id_staff, s.Name, s.groupId, count(distinct t.id) as jobsXstaff
FROM staff s
LEFT JOIN jobqueue t ON s.id=t.staff_id
GROUP BY s.id, s.groupId
ORDER BY s.groupId, jobsXstaff
) tmp
GROUP BY groupId
下面的旧答案。
这可行,但没有我不创建的表组。您可以像以前一样简单地连接表组:
SELECT min(cstaff),tmp.id
FROM (
SELECT s.id, count( staff_id ) cstaff
FROM jobqueue t
RIGHT JOIN staff s ON t.staff_id = s.id
GROUP BY t.id
) tmp
如您所见,您需要从表人员(右连接)中获取所有值,并从其自己的表中选择id人员(s.id而不是t.staff_id)。此外,你现在必须得到tmp.id而不是staff_id。