Mysql 如何使用联接正确计算总和?

Mysql 如何使用联接正确计算总和?,mysql,sql,group-by,sum,aggregate,Mysql,Sql,Group By,Sum,Aggregate,所以我试图计算零件的数量,任务的数量,每项工作的数量,以及制造每项工作所需的时间,但是我得到了一些奇怪的结果。如果我运行这个: SELECT j.id, mf.special_instructions, count(distinct p.id) as number_of_different_parts, count(distinct t.id) as number_of_tasks, SUM(distinct j.quantity) as number_of_assem

所以我试图计算零件的数量,任务的数量,每项工作的数量,以及制造每项工作所需的时间,但是我得到了一些奇怪的结果。如果我运行这个:

SELECT
  j.id, 
    mf.special_instructions,
  count(distinct p.id) as number_of_different_parts,
  count(distinct t.id) as number_of_tasks,
  SUM(distinct j.quantity) as number_of_assemblies,
  SUM(l.time_elapsed) as time_elapsed

FROM
  sugarcrm2.mf_job mf
INNER JOIN ramses.jobs j on
  mf.id = j.mf_job_id
INNER JOIN ramses.parts p on
  j.id = p.job_id
INNER JOIN ramses.tasks t on
  p.id = t.part_id
INNER JOIN ramses.batch_log l on
  t.batch_id = l.batch_id

WHERE 
  mf.job_description                LIKE "%BACKBLAZE%" OR
  mf.customer_name                  LIKE "%BACKBLAZE%" OR
  mf.customer_ref                   LIKE "%BACKBLAZE%" OR
  mf.technical_company_name LIKE "%BACKBLAZE%" OR
  mf.description                        LIKE "%BACKBLAZE%" OR
  mf.name                                   LIKE "%BACKBLAZE%" OR
  mf.enclosure_style                LIKE "%BACKBLAZE%" OR 
    mf.special_instructions     LIKE "%BACKBLAZE%"
Group by j.id
现在我得到了准确的零件和任务编号,但时间总和不正确。有什么问题吗

当我尝试使用
distinct
时,我得到了一个非常低的数字(比如当我寻找接近10000的东西时,数字介于1和30之间)

更新:以下是创建代码:

关系如下:

  • mf_作业信息链接到作业
  • 工作有部分
  • 零件有任务
  • 任务是分批完成的
  • batch_log是一个包含任务批次的所有开始和停止的表,它有开始时间、停止时间和经过的时间

我试图从批处理日志中获取每个mf_作业的所有时间,其中一个字段中有backblaze一词,以及零件、任务和组件的数量。所有这些都需要按job.id或mf_job.id分组

您需要将查询更改为:

SELECT
  ...
  SEC_TO_TIME(SUM(TIME_TO_SEC(l.time_elapsed))) as time_elapsed
SELECT
  j.id, 
  mf.special_instructions,
  count(p.id) as number_of_different_parts,
  count(t.id) as number_of_tasks,
  SUM(j.quantity) as number_of_assemblies,
  SEC_TO_TIME(SUM(l.seconds_elapsed)) as time_elapsed

FROM
  sugarcrm2.mf_job mf
INNER JOIN ramses.jobs j on
  mf.id = j.mf_job_id
INNER JOIN ramses.parts p on
  j.id = p.job_id
INNER JOIN ramses.tasks t on
  p.id = t.part_id
INNER JOIN (
            SELECT rl.batch_id
                  , SUM(TIME_TO_SEC(rl.time_elapsed)) as seconds_elapsed
            FROM ramses.batch_log rl 
            GROUP BY rl.batch_id
            ) l ON (t.batch_id = l.batch_id)

WHERE 
  mf.job_description                LIKE "%BACKBLAZE%" OR
  mf.customer_name                  LIKE "%BACKBLAZE%" OR
  mf.customer_ref                   LIKE "%BACKBLAZE%" OR
  mf.technical_company_name         LIKE "%BACKBLAZE%" OR
  mf.description                    LIKE "%BACKBLAZE%" OR
  mf.name                           LIKE "%BACKBLAZE%" OR
  mf.enclosure_style                LIKE "%BACKBLAZE%" OR 
  mf.special_instructions           LIKE "%BACKBLAZE%"
GROUP BY j.id WITH ROLLUP
此外,类似“%”…“的
行将使查询速度变慢,因为无法使用此行的索引

如果您能够使用MyISAM,则可以对这些列使用全文索引,并使用如下代码:

WHERE MATCH(mf.job_description,mf.customer_name,mf.customer_name,...) 
      AGAINST ('BACKBLAZE' IN NATURAL LANGUAGE MODE)
请参阅:



听起来问题在于多个任务可以在同一批中,和/或多个零件可以在同一任务中。例如,假设您的作业有3个部分,每个部分都有一个任务,并且所有3个任务都在同一批中。您将为该批次添加三次时间。但是distinct也不起作用,因为如果你有5个不同的批次,它们都需要300秒,那么它们就不会被认为是distinct


在这种情况下,子查询通常是一种方法。与直接使用
batch\u log
连接不同,您可以使用一个子查询连接,该子查询选择distinct
j.id
(或
p.job\u id
)、
l.batch\u id
、和
l.time\u passed
(第一个用于连接,第二个用于正确计算distinct,第三个用于实际使用的值)。然后,您可以对从那里经过的时间进行求和。这样,每个批次只计算一次。

尝试将查询重写为:

SELECT
  ...
  SEC_TO_TIME(SUM(TIME_TO_SEC(l.time_elapsed))) as time_elapsed
SELECT
  j.id, 
  mf.special_instructions,
  count(p.id) as number_of_different_parts,
  count(t.id) as number_of_tasks,
  SUM(j.quantity) as number_of_assemblies,
  SEC_TO_TIME(SUM(l.seconds_elapsed)) as time_elapsed

FROM
  sugarcrm2.mf_job mf
INNER JOIN ramses.jobs j on
  mf.id = j.mf_job_id
INNER JOIN ramses.parts p on
  j.id = p.job_id
INNER JOIN ramses.tasks t on
  p.id = t.part_id
INNER JOIN (
            SELECT rl.batch_id
                  , SUM(TIME_TO_SEC(rl.time_elapsed)) as seconds_elapsed
            FROM ramses.batch_log rl 
            GROUP BY rl.batch_id
            ) l ON (t.batch_id = l.batch_id)

WHERE 
  mf.job_description                LIKE "%BACKBLAZE%" OR
  mf.customer_name                  LIKE "%BACKBLAZE%" OR
  mf.customer_ref                   LIKE "%BACKBLAZE%" OR
  mf.technical_company_name         LIKE "%BACKBLAZE%" OR
  mf.description                    LIKE "%BACKBLAZE%" OR
  mf.name                           LIKE "%BACKBLAZE%" OR
  mf.enclosure_style                LIKE "%BACKBLAZE%" OR 
  mf.special_instructions           LIKE "%BACKBLAZE%"
GROUP BY j.id WITH ROLLUP
批次(l)表没有名为time_Appeased的字段 任务就是这样的

SUM(t.time_elapsed) as time_elapsed
-或


@Icarus,非常接近,
选择秒到秒时间(总和(时间到秒(已用时间))
实际上是正确的,函数
SECOND()
将只给出59秒的最大结果。请包括表架构。并明确表示为基于批处理id或批处理id+作业的总和的已用时间_id@dah您能从show create table中给出列ddl吗?这里相关的是了解表之间关系的行为。基本上,连接会导致重复。然后,您可能需要使用嵌套子查询进行不同级别的聚合。你对表及其关系描述得越多越好。+1表示你几乎所有的代表都参与了赏金活动。实际上我们正在使用innodb,我尝试更改查询,但现在我仍然得到了错误的秒数。