来自多个表的MySQL结果计数得到错误结果?
我有三个表格:出勤率、简历目标和候选人。我需要找到特定用户的候选计数 我不是MySQL的专家。我尝试了下面的查询,但找不到确切的值来自多个表的MySQL结果计数得到错误结果?,mysql,sql,aggregate-functions,Mysql,Sql,Aggregate Functions,我有三个表格:出勤率、简历目标和候选人。我需要找到特定用户的候选计数 我不是MySQL的专家。我尝试了下面的查询,但找不到确切的值 SELECT attendance_date, cv_target_date_for, cv_requirement, job_id, cv_target, achi, recruiter_comment, recruiter_rating FROM attendance f RIGHT JOIN (
SELECT
attendance_date,
cv_target_date_for,
cv_requirement,
job_id,
cv_target,
achi,
recruiter_comment,
recruiter_rating
FROM
attendance f
RIGHT JOIN
(
SELECT
cv_requirement,
cv_target,
cv_target_date_for,
achi,
recruiter_comment,
recruiter_rating
FROM
cv_target a
LEFT JOIN
(
SELECT
COUNT(candidate_id) AS achi,
cv_target_date,
fk_job_id
FROM
candidate
GROUP BY
fk_job_id,
cv_target_date
) b
ON a.cv_requirement = b.fk_job_id
AND a.cv_target_date_for = b.cv_target_date
WHERE
cv_target_date_for BETWEEN '2014-02-01' AND '2014-03-01'
AND cv_recruiter = '36'
) c
ON f.attendance_date=c.cv_target_date_for
GROUP BY
cv_requirement,
cv_target_date_for
ORDER BY
c`.`cv_target_date_for` ASC
出席
id fk_user_id attendance_date
1 44 2014-02-24
2 44 2014-02-25
3 44 2014-02-26
4 44 2014-02-27
5 36 2014-02-24
6 44 2014-02-28
cv_目标
id cv_recruiter cv_requirement cv_target cv_target_date_for
1 44 1 3 2014-02-24
2 44 2 2 2014-02-24
3 44 3 2 2014-02-25
4 44 4 3 2014-02-25
4 44 4 3 2014-02-26
候选人
candidate_id fk_posted_user_id fk_job_id cv_target_date
1 44 1 2014-02-24
2 44 3 2014-02-25
3 44 3 2014-02-25
3 44 4 2014-02-25
4 44 4 2014-02-26
5 44 5 2014-02-28
5 44 5 2014-02-28
期望结果
attendance_date cv_target_date_for job_id cv_target achi(count)
2014-02-24 2014-02-24 1 3 1
2014-02-24 2014-02-24 2 2 null
2014-02-25 2014-02-25 3 2 2
2014-02-25 2014-02-25 4 3 1
2014-02-26 2014-02-26 4 3 1
2014-02-27 2014-02-27 null null null
2014-02-28 null 5 null 2
我得到的输出
attendance_date cv_target_date_for job_id cv_target achi(count)
2014-02-24 2014-02-24 1 3 1
2014-02-24 2014-02-24 2 2 null
2014-02-25 2014-02-25 3 2 2
2014-02-25 2014-02-25 4 3 1
2014-02-26 2014-02-26 4 3 1
日期27和28未显示。我还需要这些值。原始答案
我想我知道你想要什么。以下假设您希望特定用户的所有出席日期都在特定范围内。对于每个出席日期,您都需要所有cv_目标记录(如果有)。对于其中的每一个,你需要一个候选人的计数
使用子查询获取计数。这是子查询中唯一需要处理的部分。仅在子查询中使用GROUP BY
表达式,而不在外部查询中使用。仅选择所需的字段
使用LEFT JOIN
从表达式左侧的表中获取所有记录,并仅从右侧的表中获取匹配的记录。因此,来自考勤的所有记录(与WHERE表达式匹配)和来自cv_target的匹配记录(无论它们在候选子查询中是否匹配),然后匹配来自候选子查询的记录
试试这个:
SELECT
DATE_FORMAT(a.attendance_date, '%Y-%m-%d') AS attendance_date,
DATE_FORMAT(t.cv_target_date_for, '%Y-%m-%d') AS cv_target_date_for,
t.cv_requirement AS job_id,
t.cv_target,
c.achi AS `achi(count)`
FROM
attendance AS a
LEFT JOIN
cv_target AS t
ON a.fk_user_id = t.cv_recruiter
AND a.attendance_date = t.cv_target_date_for
LEFT JOIN
(
SELECT
COUNT(candidate_id) AS achi,
fk_job_id,
cv_target_date
FROM
candidate
WHERE
fk_posted_user_id = 44
AND cv_target_date BETWEEN '2014-02-01' AND '2014-03-01'
GROUP BY
fk_job_id,
cv_target_date
) AS c
ON t.cv_requirement = c.fk_job_id
AND t.cv_target_date_for = c.cv_target_date
WHERE
a.fk_user_id = 44
AND a.attendance_date BETWEEN '2014-02-01' AND '2014-03-01'
ORDER BY
ISNULL(t.cv_target_date_for), t.cv_target_date_for, t.cv_requirement
请注意,要获得正确的结果,不需要以下行。但是,根据数据库结构和数据量的不同,它可能会提高性能
AND cv_target_date BETWEEN '2014-02-01' AND '2014-03-01'
该函数用于将NULL
排序到底部
我已经创建了一个显示您请求的输出的窗口,除了的cv\u target\u date\u。不可能输出数据中不存在的值
更新
有了新的数据和检索数据的新要求,cv_target或候选人具有特定出勤日期的数据,您需要添加另一个表来获取工作ID。在你最初的问题中,你有一张有身份证号码和职位的表格,但没有日期
您可能需要重新考虑数据库设计。我不确定我是否理解您的表是如何相互关联的,但候选表的这两条新记录似乎是孤立的。所有联接都基于日期,但似乎没有将作业ID号链接到日期的表
您可以通过对cv_目标和候选者进行并集
来创建派生表。然后使用派生表作为联接的左侧
更新的查询:
SELECT
DATE_FORMAT(a.attendance_date, '%Y-%m-%d') AS attendance_date,
DATE_FORMAT(t.cv_target_date_for, '%Y-%m-%d') AS cv_target_date_for,
j.job_id,
t.cv_target,
c.achi AS `achi(count)`
FROM
attendance AS a
LEFT JOIN
(
SELECT
cv_requirement AS job_id,
cv_target_date_for AS job_date
FROM
cv_target
WHERE
cv_recruiter = 44
AND cv_target_date_for BETWEEN '2014-02-01' AND '2014-03-01'
UNION
SELECT
fk_job_id AS job_id,
cv_target_date AS job_date
FROM
candidate
WHERE
fk_posted_user_id = 44
AND cv_target_date BETWEEN '2014-02-01' AND '2014-03-01'
) AS j
ON a.attendance_date = j.job_date
LEFT JOIN
cv_target AS t
ON a.fk_user_id = t.cv_recruiter
AND j.job_id = t.cv_requirement
AND j.job_date = t.cv_target_date_for
LEFT JOIN
(
SELECT
COUNT(candidate_id) AS achi,
fk_job_id,
cv_target_date
FROM
candidate
WHERE
fk_posted_user_id = 44
AND cv_target_date BETWEEN '2014-02-01' AND '2014-03-01'
GROUP BY
fk_job_id,
cv_target_date
) AS c
ON j.job_id = c.fk_job_id
AND j.job_date = c.cv_target_date
WHERE
a.fk_user_id = 44
AND a.attendance_date BETWEEN '2014-02-01' AND '2014-03-01'
ORDER BY
ISNULL(t.cv_target_date_for), t.cv_target_date_for, j.job_id
我已经创建了一个更新版,显示您请求的输出,除了
的cv\u target\u date\u。无法输出数据中不存在的值(即2014-02-27)
如果这是一个输入错误,您的意思是2014-02-28,那么您需要从派生表而不是cv_目标表中选择日期。您可能应该更改结果中的列标题,因为它不再是
date的cv\u target\u date\u
要从cv_目标或候选人获取日期,请更改此行:
DATE_FORMAT(t.cv_target_date_for, '%Y-%m-%d') AS cv_target_date_for,
为此:
DATE_FORMAT(j.job_date, '%Y-%m-%d') AS job_date,
您可能需要通过表达式调整顺序以满足您的需要。thanx我已经完成了相同的事情,但您的查询格式非常复杂。我还需要一件我无法完成的事情,如果有出勤日期,没有设置目标,并且有候选人计数,那么我们如何显示出勤日期cv\u目标日期\u为空且ACHI(计数)=2?我已经更新了候选人表和期望的结果,请查看一下,因此您需要所有简历目标记录和每个出勤日期的所有候选人记录,无论简历目标和候选人之间是否匹配?您需要另一个表来获取简历要求/fk_工作ID的可能ID号。您是否有一个作为特定日期的所有可能的职务ID?目前看来,您添加到候选表中的这两条记录似乎是孤立的。@user3364940您可以通过与cv_目标表和候选表合并来创建职务ID的派生表。但是,如果cv_目标日期为2014-02-27 beca,则不可能得到结果使用您提供的数据中任何地方都不存在的。您需要更改数据或所需结果。