#mysql
#MySQL
Вопрос:
У меня есть 3 таблицы, tb_orders
, tb_tasks
amp; tb_userconfig
которые я пытаюсь запросить, но кажется, что при выполнении запроса с обоими операторами inner join COUNT()
он полностью искажен, однако при попытке выполнить запрос только с одним оператором inner join все, кажется, работает (за вычетом одного столбца, который я бы пропустил)
Пример структуры таблицы:
tb_orders
| OrderedBy | OrderDate |
|-----------|--------------|
| persona | 29/6/21 0:00 |
| persona | 29/6/21 0:00 |
| personc | 29/6/21 0:00 |
| personb | 29/6/21 0:00 |
tb_userconfig
| EmployeeName | Username |
|--------------|----------|
| Person A | persona |
| Person B | personb |
| Person C | personc |
tb_tasks
| AssigneeUser |
|--------------|
| Persom A |
| Person B |
| Person C |
| Person B |
Запрос:
SELECT T1.EmployeeName, T1.Username, Count(T2.OrderedBy) AS OrderCount, Count(T3.AssigneeUser) AS TaskCount
FROM tb_userconfig AS T1
INNER JOIN (
SELECT OrderedBy, OrderDate FROM tb_orders
) AS T2 on T1.Username = T2.OrderedBy
INNER JOIN (
SELECT AssigneeUser FROM tb_tasks
) AS T3 on T1.EmployeeName = T3.AssigneeUser
GROUP BY T1.EmployeeName ORDER BY T1.EmployeeName
Желаемый результат:
| EmployeeName | Username | OrderCount | TaskCount |
|--------------|----------|------------|-----------|
| Person A | persona | 2 | 1 |
| Person B | personb | 1 | 2 |
| Person C | personc | 1 | 1 |
Любые идеи о том, почему оператор приведет к искаженным подсчетам и не даст желаемого результата?
TIA
Комментарии:
1. Можете ли вы добавить искаженный результат?
2. Поскольку это ваш код, он ничего не вернет, потому что предложение ON во 2-м соединении неверно. Это должно быть:
on T1.Username = T3.AssigneeUser
. Кроме того, для этой выборки данных 2-е соединение не требуется. Итак, я предполагаю, что это не ваш реальный код, и вы слишком упростили свои фактические данные. Опубликуйте код и примеры данных, которые ближе к тому, что у вас есть, и объясните, почему вам нужно 2-е соединение.3. Ваш код возвращает ошибку, потому
sql_mode
что по умолчанию используется значение haveonly_full_group_by
(в MySQL 8.0 ), см. DBFIDDLE , который также включает изменение, предлагаемое @forpas, и упрощение того, как выполнять объединения4. @Luuk спасибо за скрипку, пожалуйста, ознакомьтесь с этим ( dbfiddle.uk /… ). Я удалил personc из tb_tasks, что приводит к искажению результатов подсчета
Ответ №1:
Вы можете упростить, предварительно агрегировав подсчеты.
Не зная ваших данных, я бы предложил использовать внешние соединения и объединяться, чтобы не обрабатывать строки, поскольку в противном случае пользователи с задачами, но без заказов или наоборот, были бы исключены.
select uc.EmployeeName, uc.username,
Coalesce(o.OrderCount, 0) OrderCount,
Coalesce(t.TaskCount, 0) TaskCount
from tb_userconfig uc
left join (
select orderedby, Count(*) OrderCount
from tb_orders
group by orderedby
) o on o.orderedby=uc.username
left join (
select AssigneeUser, Count(*) TaskCount
from tb_tasks
group by AssigneeUser
) t on t.AssigneeUser=uc.username
Комментарии:
1. Спасибо за предложение, однако, когда я пытаюсь его запустить, кажется, что
OrderCount
он заполняется, однако TaskCount предназначен0
для всех пользователей… Есть идеи?2. Пожалуйста, взгляните на эту скрипку DB dbfiddle.uk /…
3. Не совсем уверен, что вы имеете в виду, приведенный выше запрос даже не в вашей скрипке. Когда я использую запрос в своем ответе, в вашей скрипке нет нулей
4. Спасибо, похоже, я делал что-то необычное, но ваш запрос определенно работает! Спасибо за вашу помощь!