Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
来自多个表的MySQL结果计数得到错误结果?_Mysql_Sql_Aggregate Functions - Fatal编程技术网

来自多个表的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 (

我有三个表格:出勤率、简历目标和候选人。我需要找到特定用户的候选计数

我不是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
         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,则不可能得到结果使用您提供的数据中任何地方都不存在的。您需要更改数据或所需结果。