Получить общее количество записей с соединением mysql и 2 таблицами

У меня есть 2 таблицы, к которым я пытаюсь присоединиться, но я не уверен, как сделать это наиболее эффективным по времени.

Таблица задач:

nid | created_by | claimed_by | urgent
1   |     11     |     22     |   1
2   |     22     |     33     |   1
3   |     33     |     11     |   1
1   |     11     |     43     |   0
1   |     11     |     44     |   1

Таблица сотрудников:

userid | name
  11   |  EmployeeA
  22   |  EmployeeB
  33   |  EmployeeC

Результат, который я пытаюсь получить:

userid | created_count | claimed_count | urgent_count
  11   |       3       |       1       |       3
  22   |       1       |       1       |       2
  33   |       1       |       1       |       2

В столбце created_account будет показано общее количество задач, созданных этим пользователем.

В столбце claimed_count будет показано общее количество задач, заявленных этим пользователем.

В столбце urgent_count будет показано общее количество срочных задач (созданных или заявленных) этим пользователем.

Заранее спасибо!


person 626    schedule 23.07.2015    source источник
comment
Просто напишите запрос и протестируйте его. Затем, когда он окажется слишком медленным, попробуйте его оптимизировать. Если вам это не удастся, вы можете опубликовать свою попытку вместе со структурой таблицы, индексами, объемами данных и другой соответствующей информацией, которая может помочь нам найти узкое место в вашем запросе. В настоящее время этот вопрос неполный.   -  person GolezTrol    schedule 23.07.2015


Ответы (1)


Я бы начал с того, что разбил бы это на части, а затем собрал бы их вместе. Вы можете получить created_count иclaim_count, используя простую агрегацию следующим образом:

SELECT created_by, COUNT(*) AS created_count
FROM myTable
GROUP BY created_by;

SELECT claimed_by, COUNT(*) AS claimed_count
FROM myTable
GROUP BY claimed_by;

Чтобы получить количество срочных действий для каждого сотрудника, я бы объединил две таблицы при условии, что сотрудник является либо столбцом created_by, либо затребованным_by, и сгруппировал по сотруднику. Однако вместо подсчета я бы использовал SUM(). Я делаю это, потому что кажется, что каждая строка будет либо 0, либо 1, поэтому SUM() будет эффективно подсчитывать все ненулевые строки:

SELECT e.userid, SUM(t.urgent)
FROM employee e
JOIN task t ON e.userid IN (t.created_by, t.claimed_by)
GROUP BY e.userid;

Теперь, когда у вас есть все необходимые биты данных, вы можете использовать внешнее соединение, чтобы соединить все эти подзапросы с таблицей сотрудников, чтобы получить их количество. Вы можете использовать функцию COALESCE(), чтобы заменить любые нулевые значения на 0:

SELECT e.userid, COALESCE(u.urgent_count, 0) AS urgent_count, COALESCE(crt.created_count, 0) AS created_count, COALESCE(clm.claimed_count, 0) AS claimed_count
FROM employee e
LEFT JOIN(
  SELECT e.userid, SUM(t.urgent) AS urgent_count
  FROM employee e
  JOIN task t ON e.userid IN (t.created_by, t.claimed_by)
  GROUP BY e.userid) u ON u.userid = e.userid
LEFT JOIN(
  SELECT claimed_by, COUNT(*) AS claimed_count
  FROM task
  GROUP BY claimed_by) clm ON clm.claimed_by = e.userid
LEFT JOIN(
  SELECT created_by, COUNT(*) AS created_count
  FROM task
  GROUP BY created_by) crt ON crt.created_by = e.userid;

Вот пример SQL Fiddle.

person AdamMc331    schedule 23.07.2015