Fórum Root.cz
Hlavní témata => Software => Téma založeno: Zopper 07. 10. 2011, 19:40:45
-
Mám v databázi takovouto tabulku (zjednodušeno):
+------+-------+--------+
| name | login | logout |
+------+-------+--------+
| u1 | 12:10 | 13:15 |
| u1 | 14:20 | NULL |
| u2 | 12:00 | 13:00 |
| u2 | 14:00 | 14:10 |
| u2 | 15:55 | NULL |
+------+-------+--------+
Z ní potřebuji vybrat poslední záznam ke každému identifikátoru ve sloupci name (který ale ve výpisu bude každý jen jednou) - tzn poslední aktivitu uživatelů.
Snažil jsem se použít DISTINCT, ale ten unikátnost vztahuje na celý výběr a nenapadá mě už žádné jiné řešení (ani při využití subdotazů). Rád bych se vyhnul jakémukoliv dalšímu zpracování a filtrování v aplikaci.
-
Tak po nějakém válčení se mi povedlo dát dohromady tento příkaz, který (zdá se) dělá co potřebuji.
SELECT * FROM tabulka
WHERE
login=(
SELECT MAX(login) FROM tabulka
WHERE (
name IN (SELECT DISTINCT name FROM tabulka)
)
AND logout IS NOT NULL
)
OR logout IS NULL
ORDER BY name ASC;
Pokud by ale někdo přišel na řešení s menším počtem subdotazů, dejte vědět. :-)
-
Kombinacia group by a distinct?
-
Dík za postrčení, nakonec to jde i bez DISTINCT a jediným příkazem:
SELECT name, MAX(login), MAX(logout) FROM tabulka GROUP BY name ORDER BY name ASC;
-
Ta poslední varianta je ale špatně. Neřeší to paralelní přihlášení (nevím, zda se mohou uživatelé přihlašovat paralelně) a neřeší to null hodnoty ve sloupci logout (které tam evidentně jsou).
Zkusím nejdřív zpřesnit zadání. Pro každé name chceme v tabulce najít řádek s maximální hodnotou login. Výsledné řádky chceme řadit vzestupně podle name. Předpokládáme, že name a login nemohou být null. Dále předpokládáme, že pro každé name existuje hledaný řádek právě jeden.
Potom lze dotaz napsat takto:
select a.*
from tabulka a inner join (
select name, max(login) as login
from tabulka
group by name
) b on a.name = b.name and a.login = b.login
order by a.name
Nemám nikde po ruce MySQL, takže to nevyzkouším, ale mělo by to fungovat. Samozřejmě to lze napsat i jinak (např. s použitím IN místo joinu).
-
Pavel: Máš pravdu, ty NULL hodnoty mě v tu chvíli vůbec nedošly. Každopádně tvůj příkaz funguje v pořádku, díky.
-
Zalezi co je posledni aktvita uzivatele a zda je mozne paralelni prihlaseni. Pokud paralelni nelze, tak staci obycejne group by s max pro login i logout (tam vhodne osetrit null, aby byl "nejvetsi"). Pokud paralelni lze, tak posledni aktivita nezalezi (asi?) na loginu, ale na logoutu - tzn. treba reseni o kus vyse, ale ridici by byl logout.