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

MySQL-仅获取在一列中有两个特定不同值的用户ID的记录,mysql,sql,sqlyog,Mysql,Sql,Sqlyog,在我的log_考勤表中有员工记录,我只想得到i(输入)和O(输出)上有mu 3和mu 4的员工,例如在这个表中,我只会得到garcia、arena、imperial和macandil记录,因为他们有mu 3和mu 4 SELECT Emp_name, loc, dept_name, DATE(CheckTime) AS date, TIME(CheckTime) AS time, CheckType AS type, mu AS device, COUNT(*)

在我的log_考勤表中有员工记录,我只想得到i(输入)和O(输出)上有mu 3和mu 4的员工,例如在这个表中,我只会得到garcia、arena、imperial和macandil记录,因为他们有mu 3和mu 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 


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

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;

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

我们忽略了“日期”和“时间”列。我们有点怀疑,这些专栏上可能也有一些尚未说明的情况

(如果我们能够理解并准确描述规范,这场战斗就胜利了一半。)

有两种方法

最容易理解的方法之一是使用
EXISTS
谓词来测试是否存在另一行。下面是一种获取满足规范的
Emp\u 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\u名称
,我们就完成了。但是如果我们想返回那些
Emp_name
的所有行,我们可以在join操作中使用该结果。为此,我们可以将查询包装在parens中,并将其用作内联视图,在
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
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 
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
的所有详细信息行

如果不将所有行折叠成一行,我们无法将聚合函数(例如,
COUNT(*)
添加到
SELECT
列表中。在我们这么做之前,我们需要了解我们想要回报什么

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

还有其他几种方法可以获取
Emp_name
列表,它们既有
mu=3
行,也有
mu-4

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

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
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 
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
,其中至少有三个可能值中的两个为
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.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
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 
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
              )
我们可以使用(subquery)
谓词中的两个
Emp\u name获得等效结果,其中一个子查询返回具有
mu=3
行的Emp\u name列表,另一个子查询返回具有
mu=4
行的Emp\u name列表

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


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

。。。当你运行你的查询时,会发生什么?查询是我上面截图的结果。这真的是很棒的东西,很棒的答案和很棒的解释!谢谢你,斯宾塞关于你的解释我真的学到了很多斯宾塞,谢谢!我在复习,我注意到我的答案中的查询在
checktime
locu id
列上没有谓词(条件测试),OP查询就是这样做的。(OP可能已经发现了这一点,在上面的查询中,需要在每个WHERE子句中添加等效谓词:在外部查询以及内联视图和EXISTS子查询中。很抱歉,如果您看到上面的屏幕截图,当我运行查询时,它不会显示任何记录,这就是它显示的结果