Autor | Zpráva | ||
---|---|---|---|
Sabr Profil * |
#1 · Zasláno: 8. 7. 2009, 23:02:58
Ahoj,
dlouho jsem s mysql nedělal a teď si nevím rady ani s tímto "jednoduchým" sql dotazem... Mám dvě tabulky: CREATE TABLE IF NOT EXISTS `srank` ( `id` int(11) NOT NULL AUTO_INCREMENT, `id_web` int(11) NOT NULL, `srank` int(11) NOT NULL, `date` date NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci AUTO_INCREMENT=12 ; INSERT INTO `srank` (`id`, `id_web`, `srank`, `date`) VALUES (1, 1, 70, '2009-07-08'), (2, 1, 60, '2009-07-07'), (3, 2, 50, '2009-07-09'), (4, 2, 100, '2009-07-23'), (5, 1, 10, '2009-08-26'), (6, 1, 90, '2009-09-29'), (7, 3, 10, '2009-08-26'), (8, 3, 90, '2009-09-29'), (9, 3, 10, '2009-08-26'), (10, 2, 90, '2009-09-29'), (11, 2, 100, '2010-07-30'); CREATE TABLE IF NOT EXISTS `webs` ( `id` int(11) NOT NULL AUTO_INCREMENT, `www` varchar(100) COLLATE utf8_czech_ci NOT NULL DEFAULT '', `title` varchar(100) COLLATE utf8_czech_ci NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci AUTO_INCREMENT=4 ; INSERT INTO `webs` (`id`, `www`, `title`) VALUES (1, 'http://seznam.cz', 'Seznam.cz'); (2, 'http://centrum.cz', 'Centrum.cz'); (3, 'http://novinky.cz', 'Novinky.cz'); Co teď potřebuji? Potřebuji vypsat všechny weby, takže to bude LEFT JOIN a ke každému webu nejnovější SRANK. Čili něco takového: Seznam.cz | 90 | 2009-09-29 Centrum.cz | 100 | 2010-07-30 Zkoušel jsem něco takového, ale nefunguje správně: SELECT w.title, w.www, s.srank, s.date FROM webs AS w LEFT JOIN srank AS s ON w.id = s.id_web WHERE s.date = (select max(s.date) from srank AS s, webs AS w WHERE w.id = s.id_web) |
||
Sabr Profil * |
#2 · Zasláno: 8. 7. 2009, 23:03:50
A díky za odpověď :-)
|
||
TomášK Profil |
#3 · Zasláno: 9. 7. 2009, 00:24:03 · Upravil/a: TomášK
Ten subselect vybere vždy jen jeden záznam - ten s nejvyšším datem v celé databázi, je potřeba to upravit, aby vybral nejvyšší datum jen pro konkrétní web, pravděpodobně si to chtěl takto:
SELECT w.title, w.www, s.srank, s.date FROM webs AS w LEFT JOIN srank AS s ON w.id = s.id_web WHERE s.date = (select max(s.date) from srank AS s WHERE w.id = s.id_web) Korelované poddotazy nemám rád - navíc se to nechová správně pokud tam web žádný srank nemá - NULL = NULL se vyhodnotí jako NULL, což se vyhodnotí jako false (nevím, jestli to nezáleží na nějakém nastavení, ale v mé databázi to takto funguje) a WHERE podmínkou to neprojde. Napadá mě řešení přes dva LEFT JOINy: SELECT w.title, w.www, s.srank, s.`date` FROM webs AS w LEFT JOIN ( SELECT id_web, MAX(srank.date) AS `date` FROM srank GROUP BY id_web) AS latest ON w.id = latest.id_web LEFT JOIN srank AS s ON s.id_web = latest.id_web AND s.date = latest.date; chválím za dobře položený dotaz :) |
||
Kajman_ Profil * |
#4 · Zasláno: 9. 7. 2009, 08:58:49
navíc se to nechová správně pokud tam web žádný srank nemá
To by mělo stačit přesunout tu podmínku také do joinu, tedy and místo where. A k tomu druhému řešení jen drobnost, že pokud se můžete spolehnout na to, že srank.id je vždy větší při větším srank.date, tak bych použil id. Na primárním klíči to bude rychlejší a nestane se, že se zdvojí web, když jsou k němu v poslední den dvě měření. |
||
Sabr Profil * |
#5 · Zasláno: 9. 7. 2009, 10:44:21
Kajman_
TomášK Díky pánové, na tohle fórum se mohu vždy spolehnout. |
||
Časová prodleva: 15 let
|
Toto téma je uzamčeno. Odpověď nelze zaslat.
0