MySQL — передать идентификатор во вложенный запрос

#mysql #nested #sum

#mysql #вложенный #сумма

Вопрос:

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

Таблица 1:

 userid, fname, lname
  

Таблица 2:

 assigned_to (is = to userid from other table), 
est_hours (est = Estimate hours),
act_hours (act = Actual Hours), 
completed_date 
  

Мне нужны только est_hours из записей, которые были отмечены как завершенные (путем указания значения в столбце completed_date. act_hours будет пустым, если значение completed_date пусто)

Проблема с моим запросом в том, что я не получаю правильные значения для суммы act_hours и est_hours . Я думаю, что это связано с тем, что вложенный запрос не соответствует правильному идентификатору пользователя. Запрос:

 SELECT userid, 
       fname, 
       lname, 
       SUM(act_hours) (SELECT SUM(est_hours) 
                       from Table2 
                       WHERE completed_date IS NULL) AS total_hours 
FROM TABLE2, 
TABLE1 
WHERE TABLE1.userid = TABLE2.assigned_to 
GROUP BY userid;
  

Я знаю, что мне нужно каким-то образом передать идентификатор пользователя из ВНЕШНЕГО запроса во внутренний запрос, чтобы СУММА (est_hours) получала сумму только для этого пользователя.

Я продолжаю ходить по кругу, и у меня болит мозг, поэтому любая помощь приветствуется!!

Ответ №1:

Не используйте неявный синтаксис соединения, это анти-шаблон

Вместо этого используйте явные объединения:

 SELECT 
  t1.userid, 
  t1.fname, 
  t1.lname, 
  SUM(t2.act_hours) (SELECT SUM(t3.est_hours) 
                     FROM Table2 t3
                     WHERE t3.completed_date IS NULL
                       AND t3.assigned_to = t1.userid) AS total_hours 
FROM table2 t2
INNER JOIN table1 t1 ON (t1.userid = t2.assigned_to)
GROUP BY userid;
  

Решение вашей головной боли заключается в использовании псевдонимов таблиц, тогда вы сможете ссылаться на разные экземпляры одной и той же таблицы.
Я настоятельно рекомендую всегда заменять все поля псевдонимом таблицы, чтобы не было путаницы, из какой (экземпляра какой) таблицы взято поле.
Это также сократит ваши строки и сделает ваш запрос более читабельным.

Комментарии:

1. в строке со 2-го по последнюю есть пробел ‘)’.. Куда должен идти «(«?

Ответ №2:

Это действительно в SQL Server, попробуйте в MYSQL, может сработать:

 SELECT userid, 
       fname, 
       lname, 
       (SELECT SUM(est_hours) SUM(act_hours) 
                       from Table2 
                       WHERE completed_date IS NULL and TABLE2.assigned_to=TABLE1.userid) AS total_hours 
FROM 
TABLE1 
  

Хорошо, возвращаюсь к моему исходному запросу…

 SELECT userid, 
       fname, 
       lname, 
       SUM(act_hours) (SELECT SUM(est_hours) 
                       from Table2 
                       WHERE completed_date IS NULL 
                       AND Table2.assigned_to=Table1.userid) 
       AS total_hours 
FROM TABLE2, 
TABLE1 
WHERE TABLE1.userid = TABLE2.assigned_to 
GROUP BY userid;
  

Комментарии:

1. -1, допустимый синтаксис есть, но результат не тот же, потому act_hours что не должен быть осуществлен с помощью where completed_date IS NULL

2. Не совсем работает. В вашем запросе используется параметр completed_date, равный нулю как для est_hours, так и для act_hours . Но act_hours будет содержать значение больше нуля только тогда, когда оно помечено как завершенное и в completed_date введена дата.