Portál AbcLinuxu, 6. května 2024 18:24


Dotaz: SQL dotaz na posledni zaznam vztazeny k uzivateli

31.3.2016 13:01 RadekXxX | skóre: 9
SQL dotaz na posledni zaznam vztazeny k uzivateli
Přečteno: 2629×
Odpovědět | Admin
Dobry den, mam tabulku treba knihovna, tam jsou sloupce:

DatumVypujcky, NazevKnihy, Uzivatel

potreboval bych sestavit dotaz na to, aby se me vypsaly vsichni uzivatele s posledni vypujcenou knihou (! pouze posledni zaznam od kazdeho uzivatele !). Muzete mi prosim nekdo poradit, jestli to vubec lze bez pouziti nejakych procedur, jedna se o MySQL ?

Diky za rady

Řešení dotazu:


Nástroje: Začni sledovat (0) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

31.3.2016 14:10 RadekXxX | skóre: 9
Rozbalit Rozbalit vše Re: SQL dotaz na posledni zaznam vztazeny k uzivateli
Odpovědět | | Sbalit | Link | Blokovat | Admin
Tak jsem to vyresil:

SELECT * FROM Knihovna WHERE DatumVypujcky IN(SELECT MAX(DatumVypujcky) FROM Knihovna GROUP BY Uzivatel)
31.3.2016 14:34 Filip Jirsák
Rozbalit Rozbalit vše Re: SQL dotaz na posledni zaznam vztazeny k uzivateli
Ještě musíte udělat vazbu mezi sloupci Uzivatel toho vnějšího a vnořeného SELECTu. Tohle by vám fungovalo jenom tehdy, kdyby si každý den půjčil jenom jeden uživatel.
1.4.2016 07:43 RadekXxX | skóre: 9
Rozbalit Rozbalit vše Re: SQL dotaz na posledni zaznam vztazeny k uzivateli
Tohto nejak nechapu. DatumVypujcky ma datovy typ DateTime a ty uzivatele by to melo odelit pomoci "GROUP BY Uzivatel". Nebo jak jinak ten dotaz formulovat ? Jeste otestuji. Diky
1.4.2016 10:03 Filip Jirsák
Rozbalit Rozbalit vše Re: SQL dotaz na posledni zaznam vztazeny k uzivateli
Ten vnitřní SELECT vám vrátí, že bylo něco vypůjčeno např. 1. 1. 2016 – a je to pro GROUP BY Uzivatel třeba Franta, ale to ten SELECT nevrací. Vnější SELECT pak najde všechny výpůjčky z 1. 1. 2016. Musíte si z toho vnitřního SELECTu vrátit i toho uživatele. Nevím, zda MySQL podporuje konstrukci (Uzivatel, DatumVypujcky) IN (SELECT …) – pokud ne, musíte to přepsat na JOIN:
SELECT Knihovna.* FROM Knihovna
JOIN 
 (SELECT Uzivatel, MAX(DatumVypujcky) AS DatumVypujcky FROM Knihovna GROUP BY Uzivatel) t USING (Uzivatel, DatumVypujcky)
Pořád ale ten SELECT vrátí všechny výpůjčky uživatele v daný den. Pokud chcete jenom jednu výpůjčku, potřebujete mít nějakou sadu údajů Uzivatel+něco, která bude v rámci databáze unikátní, a podle které dokážete určit tu nejnovější výpůjčku – např. ta generovaná ID, jak píše EtDirloth. Pokud ta ID budou unikátní sama o sobě (tj. unikátní bude nejen dvojice Uzivatel,ID, ale i samotné ID), nepotřebujete do toho JOINu přidávat uživatele, protože ten už bude identifikován tím ID.
1.4.2016 09:43 EtDirloth | skóre: 11
Rozbalit Rozbalit vše Re: SQL dotaz na posledni zaznam vztazeny k uzivateli
V tvojom rieseni su dve chyby:
Po prve vid Filip Jirsák.
Po druhe, ak nie je DatumVypujcky klucom, tak nebude splnena podmienka "pouze posledni zaznam":
INSERT INTO Knihovna VALUES ('2016-03-31', 'Dracula', 'RadekXxX');
INSERT INTO Knihovna VALUES ('2016-03-31', 'Miss Betty', 'RadekXxX');
INSERT INTO Knihovna VALUES ('2016-03-31', 'The Mystery of the Sea', 'Filip Jirsák');
INSERT INTO Knihovna VALUES ('2016-04-01', 'The Jewel of Seven Stars', 'Filip Jirsák');
V MySQL by som skusil nejaku agregacnu funkciu - bud min, max, alebo group_concat:
SELECT k.DatumVypujcky, MIN(k.NazevKnihy) AS NazevKnihy, k.Uzivatel
   FROM Knihovna AS k
   JOIN (SELECT Uzivatel, MAX(DatumVypujcky) AS max_DatumVypujcky
            FROM Knihovna
            GROUP BY Uzivatel
        ) AS g ON (k.Uzivatel = g.Uzivatel AND k.DatumVypujcky = g.max_DatumVypujcky)
   GROUP BY k.Uzivatel, k.DatumVypujcky;
To vsak bude asi pomale pri vacsich Knihovnach.
Robustnejsie by bolo vyuzit namiesto MAX(DatumVypujcky) nejaky autoinkrementujuci sa primarny kluc, ktory rastie spolu s datumom, t.j. neINSERTuju sa zaznamy so starsim DatumVypujcky, nez je max(DatumVypujcky) GROUP BY Uzivatel:
SELECT * FROM Knihovna WHERE id IN (SELECT MAX(id) FROM Knihovna GROUP BY Uzivatel);
1.4.2016 16:18 logik
Rozbalit Rozbalit vše Re: SQL dotaz na posledni zaznam vztazeny k uzivateli
Odpovědět | | Sbalit | Link | Blokovat | Admin
Řešením tohoto jsou tzn. Window funkce - které však MySQL nepodporuje.

Pokud můžeš (jde o Tvůj vlastní projekt), tak přejdi na Postgres.

5.4.2016 12:55 Kazatel
Rozbalit Rozbalit vše Re: SQL dotaz na posledni zaznam vztazeny k uzivateli
Odpovědět | | Sbalit | Link | Blokovat | Admin
Souhlas s výše uvedeným. Napadlo mě ještě jedno řešení - co takhle udržovat tabulku pouze aktuálních výpůjček? Pokud si nějakou knihu vypůjčí, zapíše se záznam do této tabulky. Pokud se publikace vrátí, pak se z tabulky smaže.

Tím by mohl být slušně vyřešen performance problém s joinem a max() funkcí.
xkucf03 avatar 14.5.2016 17:23 xkucf03 | skóre: 49 | blog: xkucf03
Rozbalit Rozbalit vše Re: SQL dotaz na posledni zaznam vztazeny k uzivateli
Odpovědět | | Sbalit | Link | Blokovat | Admin

Zkus použít DISTINCT ON – prý to funguje i v MySQL.

Univerzálnějším řešením jsou Window Functions, ale ty v MySQL AFAIK nejsou.

Pokud není k dispozici ani jedno, jsou potřeba poměrně divoké poddotazy a spojování tabulek1. Pro srovnání:

[1] pokud máš málo dat a neřešíš rychlost, tak je to použitelné – jinak bych hledal spíš jiné řešení, možná i na úrovni aplikace nebo změny datového modelu…

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.