从两个表中查询Mysql(条件?)

时间:2013-10-16 07:57:58

标签: mysql sql yii

我不确定我是否正确地表达了这个标题,但是现在就这样了。我有这两个表:

表:员工

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命令。

3 个答案:

答案 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查询 - 如果你有单独的表,你可以替换它

每个groupId的

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。