Как получить СУММУ для правильного расчета с объединением? - PullRequest
19 голосов
/ 29 августа 2011

Итак, я пытаюсь подсчитать количество деталей, количество заданий, количество в каждом задании и время, затрачиваемое на изготовление каждого задания, но я получаю несколько забавных результатов. Если я запускаю это:

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

и теперь я получаю точные номера деталей и задач, но сумма time_elapsed не верна. В чем может быть проблема?

Когда я пытаюсь это сделать с distinct, я получаю очень низкое число (например, от 1 до 30, когда я ищу что-то ближе к 10000).

ОБНОВЛЕНИЕ: вот код создания:

http://pastebin.com/nbhU9rYh

http://pastebin.com/tdmAkNr4

http://pastebin.com/0TFCUaeQ

http://pastebin.com/fugr8C9U

http://pastebin.com/Zq0bKG2L

http://pastebin.com/k5rESUrq

Отношения такие:

  • Информация mf_job связана с заданием
  • работы имеют детали
  • части имеют задачи
  • задачи в пакетном режиме
  • batch_log - это таблица со всеми запусками и остановками для пакетов задач, у нее есть start_time, stop_time и time_elapsed.

Я пытаюсь получить все time_elapsed из batch_log для каждого mf_job со словом backblaze в одном из его полей, а также с количеством деталей, задач и сборок. Все это нужно сгруппировать по job.id или mf_job.id

Ответы [ 4 ]

3 голосов
/ 09 сентября 2011

Попробуйте переписать запрос на:

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
2 голосов
/ 30 августа 2011

Вам нужно изменить запрос на:

SELECT
  ...
  SEC_TO_TIME(SUM(TIME_TO_SEC(l.time_elapsed))) as time_elapsed

Кроме того, строка LIKE '%...' замедлит запрос, поскольку никакие индексы для этого не могут быть использованы.

Если вы можете использовать MyISAM, вы можете использовать полнотекстовый индекс для этих столбцов и использовать такой код:

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

См:
http://dev.mysql.com/doc/refman/5.5/en/fulltext-search.html
http://www.petefreitag.com/item/477.cfm
http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html#function_time-to-sec

0 голосов
/ 14 сентября 2011
Таблица

batches (l) не имеет поля с именем time_elapsed задачи делает так что либо

SUM(t.time_elapsed) as time_elapsed

-или-

SUM(l.actual_time) as time_elapsed
0 голосов
/ 08 сентября 2011

Похоже, проблема в том, что несколько задач могут быть в одном пакете, и / или несколько частей могут быть в одной задаче. Скажем, например, что ваша работа состоит из 3 частей, и каждая часть имеет задачу, и все 3 задачи находятся в одном пакете. Вы добавите время для этой партии три раза. Но отличное также не сработает, поскольку, если у вас есть 5 разных пакетов, на которые у всех ушло 300 секунд, они не будут считаться различными.

В такой ситуации подзапрос - это, как правило, путь. Вместо непосредственного соединения с batch_log вы должны присоединиться к подзапросу, который выбрал различные j.id (или p.job_id), l.batch_id и l.time_elapsed (первый предназначен для объединения, второй - только для правильного вычисления четкое и третье фактическое значение для использования). Тогда вы можете сложить l.time_elapsed оттуда. Таким образом, каждая партия считается ровно один раз.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...