MySQL - 只记录哪个用户ID在一列中有两个特定的不同值

时间:2015-05-28 01:25:31

标签: mysql sql sqlyog

在我的log_attendance表中有员工记录,我想只得到他们的I(in)和O(out)上有mu 3和4的员工,例如在这张桌子上,我会得到加西亚,竞技场,帝国和马坎迪尔只有记录,因为他们有mu 3和4。

enter image description here

SELECT 
  Emp_name,
  loc,
  dept_name,
  DATE(CheckTime) AS date,
  TIME(CheckTime) AS time,
  CheckType AS type,
  mu AS device,
  COUNT(*) AS summary 
FROM
  log_attendance 
WHERE DATE(CheckTime) = '2015-05-27' 
  AND loc_id = 1 
  AND mu IN (3, 4)
GROUP BY Userid,
  mu
ORDER BY dept_id, Emp_name,
  mu DESC 

2 个答案:

答案 0 :(得分:0)

我认为您只需要一个having子句并将聚合限制为员工:

SELECT UserId, Emp_name, DATE(CheckTime) AS date, TIME(CheckTime) AS time,
       COUNT(*) AS summary 
FROM log_attendance 
WHERE DATE(CheckTime) = '2015-05-27'  AND loc_id = 1 AND mu IN (3, 4)
GROUP BY Userid, Emp_Name
HAVING COUNT(DISTINCT mu) = 2;

答案 1 :(得分:0)

有几种不同的查询模式会返回指定的结果。假设__cdecl是员工的唯一标识符,并且您希望为员工返回所有行,如果至少有两行Emp_name,并且这些行中至少有一行的Emp_name值为mu,其中至少有一行的3值为mu

我们忽略了" date"和"时间"列。我们有点怀疑在这些专栏中可能存在一些尚未说明的条件。

(如果我们能够理解并准确地描述规范,那么战斗就赢了一半。)

有几种方法。

最容易理解的一个是使用4谓词来测试另一行的存在。这是获得满足规范的EXISTS的独特列表的方法。

Emp_name

如果我们只需要SELECT a.Emp_name FROM log_attendance a WHERE a.mu = '3' AND EXISTS ( SELECT 1 FROM log_attendance o WHERE o.Emp_name = a.Emp_name AND o.mu = '4' ) GROUP BY a.Emp_name ,我们就完成了。但是如果我们想要返回那些Emp_name的所有行,我们可以在连接操作中使用该结果。为此,我们可以将查询包装在parens中,并将其用作内联视图,在Emp_name子句中引用它来代替表。例如:

FROM

这将返回符合指定条件的SELECT d.Emp_name , d.loc , d.dept_name , DATE(d.CheckTime) AS `date` , TIME(d.CheckTime) AS `time` , d.CheckType AS `type` , d.mu AS `device` FROM ( -- the query from above goes here, between parens SELECT a.Emp_name FROM log_attendance a WHERE a.mu = '3' AND EXISTS ( SELECT 1 FROM log_attendance o WHERE o.Emp_name = a.Emp_name AND o.mu = '4' ) ) e JOIN log_attendance d ON d.Emp_name = e.Emp_name ORDER BY d.Emp_name, d.CheckTime 的所有详细信息行。

我们无法添加聚合功能,例如Emp_name列表COUNT(*),而不会将所有行合并为一行。在我们这样做之前,我们需要了解我们尝试返回的内容。

我们是否只想为每个SELECT返回行数?或者Emp_name的所有行的组合计数?对于那些Emp_name,我们是否需要mu=3行数和mu=4行数?我们如何编写查询取决于我们想要返回的结果集。

还有其他几种方法可以获得同时包含Emp_nameEmp_name行的mu=3列表。

我们可以获取包含mu-4mu=3的所有行,然后按mu=4对这些行进行分组,并计算Emp_name中每个行显示的不同值mu,并排除该计数不等于2的所有行。例如:

Emp_name

(此模式也适用于其他情况,例如列出SELECT a.Emp_name FROM log_attendance a WHERE a.mu IN (3,4) GROUP BY a.Emp_name HAVING COUNT(DISTINCT a.mu) = 2 至少有三个可能值Emp_name中的两个。{/ p>

此查询也可用作内联视图,与上一个查询相同。

mu

我们还可以使用具有两个SELECT d.Emp_name , d.loc , ... FROM ( SELECT a.Emp_name FROM log_attendance a WHERE a.mu IN (3,4) GROUP BY a.Emp_name HAVING COUNT(DISTINCT a.mu) = 2 ) e JOIN log_attendance d ON d.Emp_name = e.Emp_name ORDER BY d.Emp_name, d.CheckTime 谓词的查询来返回等效结果,例如:

EXISTS

我们可以使用两个SELECT d.Emp_name , d. FROM log_attendance d WHERE EXISTS ( SELECT 1 FROM log_attendance a WHERE a.mu = 3 AND a.Emp_name = d.Emp_name ) AND EXISTS ( SELECT 1 FROM log_attendance b WHERE b.mu = 3 AND b.Emp_name = d.Emp_name ) 谓词获得等效结果,其中一个子查询返回具有Emp_name IN (subquery)行的Emp_name列表,另一个子查询返回具有{{1}的Emp_name列表行。

请注意,此处演示的查询会返回mu=3的所有行,而不仅仅是mu = 3和mu = 4行。如果是规范的一部分,我们可以添加适当的谓词来过滤掉我们不想返回的行。

这不是一个详尽的列表,我们可以使用其他几种查询模式。