MySQL - 仅获取一列中哪些用户标识具有两个特定不同值的记录
MySQL - get only record which userids have two specific different values in one column
在我的 log_attendance table 中有雇员的记录,我想只得到 I(in) 和 O(out) 上有 mu 3 和 4 的雇员,因为关于这个例子 table,我只会得到 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
我认为您只需要一个 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;
有几种不同的查询模式可以 return 指定的结果。假设 Emp_name
是员工的唯一标识符,并且您想要 return all 员工的行,如果至少有两行 Emp_name
,并且这些行中至少有一个 mu
值为 3
,并且至少有一个行具有 mu
值为 4
。
我们忽略了 "date" 和 "time" 列。我们有点怀疑这些列也可能存在一些尚未说明的条件。
(如果我们能够理解并准确描述规范,那么这场战斗就赢了一半。)
有几种方法。
最容易理解的方法之一是使用 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
,我们就完成了。但是如果我们想要 return 那些 Emp_name
的所有行,我们可以在连接操作中使用该结果。为此,我们可以将查询包裹在括号中,并将其用作内联视图,在 FROM
子句中引用它来代替 table。例如:
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
这将 return Emp_name
满足指定条件的所有详细信息行。
我们无法添加聚合函数,例如COUNT(*)
到 SELECT
列表,而不将所有行折叠成一行。在我们这样做之前,我们需要了解我们正在尝试 return。
我们是否希望 return 只计算每个 Emp_name
的行数?或者那些 Emp_name
的所有行的组合计数?我们是否需要 mu=3
行的计数和 Emp_name
行的 mu=4
行计数?我们如何编写查询取决于我们想要的结果集 return。
还有其他几种方法可以获取包含 mu=3
和 mu-4
行的 Emp_name
列表。
我们可以获得具有 mu=3
或 mu=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
谓词的查询来 return 等效结果,例如:
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)
谓词获得等效结果,其中一个子查询 returning 具有 mu=3
行的 Emp_name 列表,另一个子查询return正在创建一个 Emp_name 的列表,其中有 mu=4
行。
请注意,此处显示的查询 return Emp_name
的所有行,而不仅仅是 mu=3 和 mu=4 行。如果那是规范的一部分,我们可以添加一个适当的谓词来过滤掉我们不想 return.
的行
这不是一个详尽的列表,我们还可以使用其他几种查询模式。
在我的 log_attendance table 中有雇员的记录,我想只得到 I(in) 和 O(out) 上有 mu 3 和 4 的雇员,因为关于这个例子 table,我只会得到 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
我认为您只需要一个 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;
有几种不同的查询模式可以 return 指定的结果。假设 Emp_name
是员工的唯一标识符,并且您想要 return all 员工的行,如果至少有两行 Emp_name
,并且这些行中至少有一个 mu
值为 3
,并且至少有一个行具有 mu
值为 4
。
我们忽略了 "date" 和 "time" 列。我们有点怀疑这些列也可能存在一些尚未说明的条件。
(如果我们能够理解并准确描述规范,那么这场战斗就赢了一半。)
有几种方法。
最容易理解的方法之一是使用 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
,我们就完成了。但是如果我们想要 return 那些 Emp_name
的所有行,我们可以在连接操作中使用该结果。为此,我们可以将查询包裹在括号中,并将其用作内联视图,在 FROM
子句中引用它来代替 table。例如:
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
这将 return Emp_name
满足指定条件的所有详细信息行。
我们无法添加聚合函数,例如COUNT(*)
到 SELECT
列表,而不将所有行折叠成一行。在我们这样做之前,我们需要了解我们正在尝试 return。
我们是否希望 return 只计算每个 Emp_name
的行数?或者那些 Emp_name
的所有行的组合计数?我们是否需要 mu=3
行的计数和 Emp_name
行的 mu=4
行计数?我们如何编写查询取决于我们想要的结果集 return。
还有其他几种方法可以获取包含 mu=3
和 mu-4
行的 Emp_name
列表。
我们可以获得具有 mu=3
或 mu=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
谓词的查询来 return 等效结果,例如:
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)
谓词获得等效结果,其中一个子查询 returning 具有 mu=3
行的 Emp_name 列表,另一个子查询return正在创建一个 Emp_name 的列表,其中有 mu=4
行。
请注意,此处显示的查询 return Emp_name
的所有行,而不仅仅是 mu=3 和 mu=4 行。如果那是规范的一部分,我们可以添加一个适当的谓词来过滤掉我们不想 return.
这不是一个详尽的列表,我们还可以使用其他几种查询模式。