Autor Zpráva
Jan Žák
Profil
Dobrý den všem,
rád bych Vás požádal o pomoc s výpisem tabulky příchodů a odchodů. Mám tabulku attendance:
INSERT INTO `attendance` (`id`, `employee_id`, `reason`, `checkin`, `checkout`, `season`) VALUES (1, 19734, 'checkin', '2015-08-27 20:32:36', '0000-00-00 00:00:00', 2015), (2, 19734, 'checkout', '0000-00-00 00:00:00', '2015-08-27 20:38:01', 2015);
a tabulku kde si ukládám idčka k příchodu a odchodu:
INSERT INTO `attendance_interval` (`checkin_id`, `checkout_id`) VALUES (0, 2), (1, 0);

Při výpisu mám co den, to řádek s položkami příchod, odchod a odpracované hodiny. Jde o to že příchod se mi vypíše, ale odchod bohužel již ne. Session uid je jenom pro rozpoznání zaměstnance.
SELECT e.uid, a.id, a.checkin, a.checkout 
FROM employees e, attendance a 
LEFT JOIN attendance_interval i ON a.id = i.checkin_id 
LEFT JOIN attendance a2 ON a2.id = i.checkout_id 
WHERE e.uid = '".$_SESSION['uid']."'"

Dokazál by jste někdo poradit, co dělám špatně?
nightfish
Profil
SELECT e.uid, a.id, a.checkin, a2.checkout...?
Jan Žák
Profil
nightfish:
díky za odpověď, jakmile dopíšu veškeré potřebné sloupce, v SELECT mám stále dav řádky a datumy se změní v 01.01.1970 00:00:00
nightfish
Profil
Jan Žák:
Tabulka `attendance_interval` obsahuje nějaké divné hodnoty, ne? Protože z dvojic (0,2) a (1,0) (resp. správněji asi (NULL, 2), (1, NULL)) nemůžu poznat, že ty dva záznamy patří k sobě. Spíš by dávalo smysl mít tam uloženou dvojici (1,2)...

Pak se dostanu k následujícímu dotazu:
SELECT `e`.`uid`, `i`.`checkin_id`, `a1`.`checkin`, `i`.`checkout_id`, (SELECT `checkout` FROM `attendance` `a2` WHERE `a2`.`id` = `i`.`checkout_id`) `checkout`
FROM `attendance_interval` `i`
LEFT JOIN `attendance` `a1` ON `a1`.`id` = `i`.`checkin_id`
LEFT JOIN `employees` `e` ON `a1`.`employee_id` = `e`.`uid`
WHERE `e`.`uid` = 19734
juriad
Profil
Pokud hodnota neexistuje, musí být NULL, nikoli 0 nebo '0000-00-00 00:00:00'.
Attendance_interval můžeš rovnou zahodit, není užitečná v této podobě, párování bych řešil nějak jinak (jestli vůbec).
Jaké všechny reason-y můžou existovat? Pokud je to jen checkin a checkout, tak dává smysl je sloučit do jediného záznamu a checkout provádět nějak chytřeji (update).
Jan Žák
Profil
Děkuji všem, mám to uděláno tak, že se příhlásím do klienta a na obrazovce mám tlačítko Příchod a Odchod. Po klepnutí na tlačítko Příchod se přes Ajax uloží záznam to tabulky attendance, kde je identifikace uživatele, checkin (aktuální datum). Do tabulky attendance_interval se v tu samou chvíli uloží záznam posledního vloženýho ID do sloupce checkin_id. Podobné to je s tlačíkem Odchod. Tam se akorát sloupce prohodí za checkout a checkout_id.

Pokud by to šlo udělat nějak jednodušeji, rád se poučím, děkuji.
nightfish
Profil
Jan Žák:
Pokud může u jednoho člověka v jeden den být maximálně jeden příchod a maximálně jeden odchod, tak: po klepnutí na tlačítko Příchod zkontroluješ, jestli existuje záznam v `attendance` pro dvojici (uživatel, den) - pokud ano, tak ignoruješ; pokud ne, přidáš nový záznam. Při zmáčknutí tlačítka "Odchod" zkontroluješ, jestli existuje záznam s příchodem - pokud ano, tak zaktualizuješ čas odchodu a máš hotovo; pokud neexistuje, nic neřešíš.

Takto postavený systém narazí v případě, že budeš chtít evidovat složitější kombinace, počínaje více dvojicemi příchodů/odchodů (u nás vcelku běžné v případě, že si člověk v průběhu dne odskočí něco zařídit), kombinací práce a půl dne dovolené, práce na firmě a služební cesty atd. - ale tady už záleží na interních požadavcích na sledování docházky.
juriad
Profil
Proč tam nemáš jediné tlačítko, které je závislé na aktuálním stavu? Příchod by vytvoříl nový řádek, odchod by updatovat sloupec checkout u řádku, který jako jediný má v checkout NULL?

Pokud někdo zapomene zaznamenat příchod nebo odchod, to se dá poznat podle denní doby (pokud se nepracuje na tři směny a pododbně), přidal bych přílušné tlačítko někam stranou, kam by uživatel musel manuálně zadat čas. V takovém případě by se poznamenalo do databáze, že byl čas doplněn dodatečně (sloupec manual_chechin/manual_chechout s hodnotou 1 namísto obyčejné 0). To by umožnilo uživateli si srovnat chyby, které omylem způsobil. Zároveň by se takové záznamy mohly reportovat nadřízenému, který by je zkouknul a případně zaměstnance pokáral.

To, co navrhuješ ty, totiž pravidelné střídání záznamů není snadné v databázi kontrolovat, ale kontrolovat, že každý záznam má vyplněný checkin a checkout je jednoduché.

Jak říká nightfish, je důležité napřed provést analýzu a mít přesně sepsané požadavky na systém a alespoň trochu rozmyšlené, jaké požadavky mohou přijít v budoucnu.

nightfish:
Víc přichodů/odchodů přece není problém, vždy bude existovat nejvýše jeden záznam s checkout IS NULL.
Jan Žák
Profil
Děkuji Vám všem za zajimavé postřehy a podněty, sice ještě nevím jak, ale pokusím se to podle vašich návrhů předělat.
Jan Žák
Profil
Dobrý den ještě jednou, tak jsem se pokusil to předělat dle vašich nápadů, ale stále si mi nedaří, když to napíšu narovinu, když vložím záznam třeba v ráno, nedaří se mi updatovat odchod, protože se mi nedaří zkontrolovat záznam v db. Mohl by mě někdo z Vás pomoci, jak toto zkontrolovat, že příchod v určitý den existuje a vložit odchod? Děkuji moc.
juriad
Profil
Stačí přece najít záznam daného zaměstnance, který je nejnovější a příchod byl v posledních 10 hodinách (to je proto, aby bylo možné lépe řešit směny), klidně tu podmínku můžeš změnit nebo vypustit.
SELECT * FROM attendance WHERE uid = 123 AND checkin > SUBDATE(NOW(), INTERVAL 10 HOUR) ORDER BY checkin DESC LIMIT 1
Toto vrátí buď 0 nebo 1 záznam.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: