Autor Zpráva
Sabr
Profil *
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 *
A díky za odpověď :-)
TomášK
Profil
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 *
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 *
Kajman_
TomášK
Díky pánové, na tohle fórum se mohu vždy spolehnout.
Toto téma je uzamčeno. Odpověď nelze zaslat.