2015-08-13 4 views
1

Я пытаюсь присоединиться к двум таблицам. Первая таблица содержит информацию о сотрудниках, такую ​​как имя номера сотрудника и т. Д. Вторая таблица содержит информацию о часах, такую ​​как номер сотрудника, статус (синхронизированный или отсутствующий), дата последнего времени, время, время, время, время день.Mysql left join не работает

У меня есть что-то вроде этого, но реальную информацию в базе данных

employees_tbl(
    employee_id INT NOT NULL AUTO_INCREMENT, 
    employee_first VARCHAR(30) NOT NULL, 
    employee_last VARCHAR(30) NOT NULL, 
    PRIMARY KEY (employee_id) 
); 
insert into employee (employee_id, employee_first, employee_last) values (1, First, Name); 
insert into employee (employee_id, employee_first, employee_last) values (2, Second, Name); 
insert into employee (employee_id, employee_first, employee_last) values (3, Third, Name); 
insert into employee (employee_id, employee_first, employee_last) values (4, Fourth, Name); 
insert into employee (employee_id, employee_first, employee_last) values (5, Fifth, Name); 

employee number, status(clocked in or out), datetime row was last updated, time clocked in, time clocked out, hours 
transactions_tbl(
    employee_id INT NOT NULL 
    status VARCHAR(3) NOT NULL, 
    datetime DATETIME NOT NULL, 
    clockin TIME, 
    clockout TIME, 
    hours TIME, 
    PRIMARY KEY (employee_id) 
); 

INSERT INTO transactions (employee_id, status, datetime, clockin, clockout, hours) VALUES (1, "OUT", "2015-08-10 05:00:00", "2015-08-10 04:00:00", "2015-08-10 05:00:00", "01:00:00"); 
INSERT INTO transactions (employee_id, status, datetime, clockin, clockout, hours) VALUES (2, "IN", "2015-08-11 05:00:00", "2015-08-11 04:00:00", ,); 
INSERT INTO transactions (employee_id, status, datetime, clockin, clockout, hours) VALUES (3, "IN", "2015-08-11 05:00:00", "2015-08-10 04:00:00", "2015-08-10 05:00:00", "01:00:00"); 

Выход я ищу, каждый работник должен иметь свое имя, и если они Clocked или в течение дня информация должна быть отображается. Если они не входили или выходили в течение дня, это должно было просто показать последний раз, когда они делали часы в или из. Он должен всегда показывать последнюю запись для сотрудника, что означает самую последнюю активность. Если они никогда не входили или выходили, он все равно должен отображать свое имя.

Запрос я использую:

'SELECT employee_id, employee_first FROM employees e left join (SELECT * FROM transactions ORDER BY datetime DESC) as t1 on e.employee_id = t1.employee_id GROUP BY t1.employee_id' 

однако это только дает мне первые 3 сотрудников и ничего для сотрудника 4 и за его пределами.

Я кодирую это в mysql и php. Я бы показал результаты в виде таблицы здесь, но не могу понять, как правильно сделать формат таблицы. Все просто запирается в большой беспорядок, который я даже не могу решить. Но, надеюсь, вы понимаете.

+0

Почему у вас есть производная таблица? Кажется, что это не является целью в вашем запросе. – FuzzyTree

+0

Мне не удалось ограничить таблицу транзакций только самой последней транзакцией для каждого сотрудника только с одним запросом. Это должно было сработать нормально, но я продолжал получать сообщения о том, что моя группа employee_id недействительна. Поэтому я попытался сделать это таким образом, и это сработало, за исключением того, что он выводит только первых трех сотрудников (у меня есть 15 в фактической таблице). – David

+1

Вы пытались изменить 'GROUP BY t1.employee_id' на' GROUP BY e.employee_id'? – BlitZ

ответ

3

Это ваш запрос:

SELECT e.employee_id, e.employee_first 
FROM employees e left join 
    (SELECT * FROM transactions ORDER BY datetime DESC) as t1 
    on e.employee_id = t1.employee_id 
GROUP BY t1.employee_id; 

Он имеет несколько основных ошибок. Первое - использование t1.employee_id в GROUP BY. Это от второй таблицы, а не от первого, так что это может быть NULL. Во-вторых, у вас есть ORDER BY в подзапросе, видимо ожидая, что что-то сделать. Я также предполагаю, что вам нужны столбцы от t1.

Основываясь на том, что вы описали, я думаю, что вы хотите:

SELECT e.employee_id, e.employee_first, t.* 
FROM employees e left join 
    (SELECT employee_id, MAX(datetime) as maxdt 
     FROM transactions 
     GROUP BY employee_id 
    ) tmax 
    on e.employee_id = tmax.employee_id left join 
    transactions t 
    on tmax.employee_id = t.employee_id and tmax.maxdt = t.datetime; 
+0

Это то, что я и предполагал, что ОП искали.Важно отметить использование двух соединений, один из которых позволяет использовать агрегатную функцию «max», а затем снова присоединяется к транзакциям, чтобы фактически получить данные, которые вам понадобятся. –

+0

MAX (datetime) был тем, как я изначально собирался с этим, но я не мог заставить его работать. Вышеуказанное предложение дает мне ошибку Неизвестный столбец «tmax.datetime» в разделе «on» I changed »и tmax.datetime = t.datetime;» to "и tmax.maxdt = t.datetime;" и это сработало. Спасибо – David

0

Вы делаете LEFT JOIN, начиная с таблицей сделок. В нем всего 3 сотрудника. Ваш код работает правильно. Если вы хотите получить всех сотрудников, сделайте правильное соединение в таблице транзакций.

0

Почему просто не

SELECT employee_id, employee_first 
FROM employees e 
LEFT JOIN transactions t1 on e.employee_id = t1.employee_id 
GROUP BY t1.employee_id 

О, кстати, причина, почему вы только получаете 3 результаты, а не 5, потому что вы делаете GROUP BY на employee_id из t1 таблицы транзакций. Если вы удалите это или измените его на e.employee_id, он должен вернуть нужные значения.

+0

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