1

不确定我是否正确地表达了标题,但它就在这里。我有这两张表:

表:员工

id      Name        groupId     Status
1       John Smith      1           1
2       John Doe        1           1   
3       Jane Smith      2           1
4       Jerry Smith     1           1

表:作业队列

id      job_id  staff_id        jobStatus
1       1       1           1
2       2       1           1   
3       5       2           1
4       7       3           0

现在,我需要做的是找到分配给他的工作量最少的员工,我可以通过查询作业队列表来做到这一点。

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

这工作正常,但问题是如果员工根本没有分配到任何工作,这个查询不会得到他们,因为它只查询工作队列表,该特定员工不会有任何条目。我需要修改查询以包含员工表,如果工作队列中没有为员工分配任何工作,那么我需要从员工表中获取员工详细信息。基本上,我需要为一个没有分配任何工作的团​​队寻找员工,如果所有员工都被分配了工作,那么找到分配工作最少的员工。可以使用一些帮助。另外,标记为 Yii,因为我想知道这是否适用于 Yii 活动记录。但是我可以接受一个可以与 Yii sql 命令一起使用的普通 sql 查询。

4

3 回答 3

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)

也许需要一些评论:

c需要查询来获取所有不同的 groupId - 如果你有单独的表,你可以替换它

notassigneduserid每个 groupId 的语句选择具有最少作业计数的用户

d需要查询来获取所有找到的“未分配用户”的实际用户名、groupId 并显示它

这是问题数据的结果:

Group   Staff           Jobs assigned
1       Jerry Smith     0
2       Jane Smith      1
于 2013-10-16T08:24:10.683 回答
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

顺便说一句,我不会尝试使用活动记录来执行此操作,它太复杂了。

于 2013-10-16T15:15:16.973 回答
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。

于 2013-10-16T08:23:03.317 回答