2013-08-02 3 views
0

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

The (упрощенный) таблицах:

стол: employee_work

employee_id name 
1 Joe 
2 Bob 
3 Jane 
4 Michelle 

стол: унос

employee_id days 
1 5 
2 10 
3 3 

стол: TimeOff

employee_id time_off_type days 
1 Carryover 2 
1 Leave 3 
1 Carryover 1 
2 Sick 4 
2 Carryover 4 
3 Leave 1 
4 Sickness 4 

Результаты Я хотел бы находятся :

employee_id, carryover.days, timeoff.days 
1 5 3 
2 10 4 
3 3 0 

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

Вот мой запрос:

Select 
    employee_work.employee_id, 
    carryover.carryover, 
    (SELECT SUM(days) FROM timeoff WHERE timeoff.time_off_type = 'Carryover' 
    AND timeoff.start_date>='2013-01-01') AS taken 
From 
    carryover Left Join 
    employee_work On employee_work.employee_id = carryover.employee_id Left Join 
    timeoff On employee_work.employee_id = timeoff.employee_id Left Join 
Where 
    carryover.carryover > 0 
Group By 
    employee_work.employee_id 

Я попытался группе в смежном запросе, но я тогда получить сказал «подзапрос возвращает более одной строки» - как я могу гарантировать, что суб-запрос является соблюдение присоединиться, поэтому он смотрит только на каждого сотрудника за раз, чтобы получить мои желаемые результаты?

ответ

1

Ответ на ваш вопрос заключается в использовании коррелированного подзапроса. Вам не нужно упоминать timeoff таблицы дважды в этом случае:

Select 
    employee_work.employee_id, 
    carryover.carryover, 
    (SELECT SUM(days) 
    FROM timeoff 
    WHERE timeoff.time_off_type = 'Carryover' and 
     timeoff.start_date>='2013-01-01' and 
     timeoff.employee_id = employee_work.employee_id 
) AS taken 
From 
    carryover Left Join 
    employee_work On employee_work.employee_id = carryover.employee_id 
Where 
    carryover.carryover > 0 
Group By 
    employee_work.employee_id; 

Альтернативная структура, чтобы сделать группировку для всех сотрудников в пункте from. Вы также можете удалить таблицу employee_work, потому что она, похоже, не используется. (Вы можете использовать carryover.employee_id для ид.)

Select co.employee_id, co.carryover, et.taken 
From carryover c Left Join 
    (SELECT employee_id, SUM(days) as taken 
     FROM timeoff 
     WHERE timeoff.time_off_type = 'Carryover' and 
      timeoff.start_date>='2013-01-01' 
    ) et 
    on co.employee_id = et.employee_id 
Where c.carryover > 0; 

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

+0

Спасибо - сначала обработано. Таблица employee_work необходима, поскольку нагрузка других полей называется формой, но я хотел попробовать и удержать вопрос релевантным и до такой степени, чтобы я удалил те, которые, следовательно, перешли к варианту 1, поскольку это было очень просто изменить. Еще раз спасибо. – bhttoan