在我的log_attendance表中有雇员的记录,我想仅获得I(in)和O(out)分别为mu 3和4的雇员,例如,在此表中,我将获得garcia,arena,imperial和macandil记录,因为它们具有mu 3和4。



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

最佳答案

有几种不同的查询模式将返回指定的结果。假设Emp_name是员工的唯一标识符,并且您想返回该员工的所有行,如果至少有两行具有该Emp_name,并且其中至少有一行的mu值为3,并且至少其中一行的mu值为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,就完成了。但是,如果我们想返回这些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_name行计数?我们如何编写查询取决于我们要返回的结果集。

还有其他几种获取具有Emp_namemu=3行的mu-4列表的方法。

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

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的三个可能值中至少有两个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)谓词获得等效的结果,一个子查询返回具有mu=3行的Emp_name列表,另一个子查询返回具有mu=4行的Emp_name列表。

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

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

关于mysql - MySQL-仅记录一列中哪些用户具有两个特定的不同值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30495723/

10-11 08:32