Autor | Zpráva | ||
---|---|---|---|
Ondra456 Profil * |
#1 · Zasláno: 4. 10. 2012, 16:33:15 · Upravil/a: Ondra456
Pěkný den, zasekl jsem se a nevím jak dál.
Potřebuji vymyslet jak se udělá následující: - Mám data seřazeny dle ID od nejvyššího po nejmenší. - Každá položka má také čístelnou hodnotu ve sloupci "hodnota". - Vyberu si třeba ID 50, které má hodnotu 3. - Potřebuji zjistit, který řádek je poslední (při sestupném řazení), který má hodnotu stejnou, nebo menší než je 3 Pro jednoduchost dám příklad: Mám data: ID 51 - hodnota: 5 ID 50 - hodnota: 3 // mám vybrán tento řádek ID 49 - hodnota: 4 ID 48 - hodnota: 7 ID 47 - hodnota: 5 // toto je poslední řádek který má hodnotu stejnou, nebo větší než je hodnota řádku s ID 50 ID 46 - hodnota: 2 ID 45 - hodnota: 6 // toto už neberu v potaz, protože na předchozím řádku je hodnota menší než 3 Řádek který potřebuju zjistit je řádek číslo 47. Bohužel na to ne a ne přijít. Předpokládám že to jde čistě MYSQL dotazem. Našel jsem tento dotaz: // zjisti první následující s menší nebo stejnou hloubkou jako rodič (určen $row[poradi]) $row = mysql_fetch_row(mysql_query("SELECT MIN(poradi) - 1, $row[hloubka] + 1 FROM diskuse WHERE poradi > $row[poradi] AND hloubka <= $row[hloubka]")); Já bych potřeboval něco podobného, akorát s trochu jiným zněním, tedy zjisti poslední následující s větší nebo stejnou hodnotou jako rodič. Ale nevím jak ten dotaz předělat. |
||
Tori Profil |
#2 · Zasláno: 4. 10. 2012, 16:50:33
Pokud už znáte ID a hodnotu před tímto dotazem, tak asi:
SELECT * FROM tabulka WHERE ID > 50 AND hodnota >= 3 ORDER BY ID LIMIT 1 SELECT t.* FROM tabulka t INNER JOIN (SELECT ID, hodnota FROM tabulka WHERE ID = 50) ref USING (ID, hodnota) WHERE t.ID > ref.ID AND t.hodnota >= ref.hodnota ORDER BY t.ID LIMIT 1 |
||
Joker Profil |
Ondra456:
„Vyberu si třeba ID 50, které má hodnotu 3.“ To by mělo být jednoduché. Když znám ID a hodnotu řádku proti kterému porovnávám: SELECT id, hodnota FROM tabulka WHERE id = (SELECT MAX(id) FROM tabulka WHERE hodnota >= hodnota AND id < id řádku) Ale podle dotazu odhaduji, že jde o vypisování nějakého stromu diskusí, na to jsou efektivnější metody. |
||
Kajman Profil |
#4 · Zasláno: 4. 10. 2012, 17:29:27
Možná něco takového
SELECT t.* FROM tabulka t CROSS JOIN (SELECT Coalesce(Min(id), 18446744073709551615) hranice FROM tabulka WHERE id > 50 AND hodnota < 3) h WHERE t.id > 50 AND t.hodnota >= 3 AND t.id < h.hranice ORDER BY t.id DESC LIMIT 1 A souhlasím, že se stromy se dá nakládat lépe. |
||
Ondra456 Profil * |
#5 · Zasláno: 4. 10. 2012, 18:14:42
Mám tento dotaz:
(výpis z Nette debuggeru) SELECT `id` FROM `comment` WHERE (`item_id` = 2) AND (`poradi` < 11) AND (`hloubka` >= 2) ORDER BY `poradi` LIMIT 1 Tedy to co psal Tori, což dělá bohužel to co jsem čekal že bude dělat. Problém je, že to funguje tak, že to vybere ID, které je poslední z celé tabulky s větší, nebo stejnou hloubkou. Jenže to je to co právě nechci. Vrátím se k předchozímu příkladu a trochu ho rozšířím: ID 51 - hodnota: 5 ID 50 - hodnota: 3 // mám vybrán tento řádek s hodnotou 3 ID 49 - hodnota: 4 ID 48 - hodnota: 7 ID 47 - hodnota: 5 // Tento potřebuji zjistit, protože následující řádek už má hodnotu menší než 3 ID 46 - hodnota: 2 ID 45 - hodnota: 3 ID 44 - hodnota: 4 ID 43 - hodnota: 5 // Dotaz mi ale vybere tento řádek ID 42 - hodnota: 1 ID 41 a menší neexistují RE: Joker, Kajman: Toto slouží k tomu, abych zjistil na jakou pozici ve stromu mám umístnit nový příspěvek. Jaká je lepší metoda? Googlil jsem a tohle byl nejlepší způsob co jsem našel (tedy určování pozice a hlouby příspěvku při ukládání). |
||
Kajman Profil |
#6 · Zasláno: 4. 10. 2012, 19:41:46
Ondra456:
Mrkněte na "traverzování kolem stromu". Nějaké ukázky práce s touto strukturou a odkazy na úvodní články naleznete např. u Jakuba. |
||
Joker Profil |
#7 · Zasláno: 4. 10. 2012, 19:46:05
Ondra456:
Řekl bych, že řešení od Tori by mělo fungovat, jen to má opačně formulovanou podmínku a řazení. SELECT * FROM tabulka WHERE ID < 50 AND hodnota >= 3 ORDER BY ID DESC LIMIT 1 Problematikou se zabývá třeba tento článek: http://interval.cz/clanky/metody-ukladani-stromovych-dat-v-relacnich-databazich/ |
||
Kajman Profil |
#8 · Zasláno: 4. 10. 2012, 19:56:02
Joker:
To taky fungovat nebude. Ale i já tam mám blbě řazení... SELECT t.* FROM tabulka t CROSS JOIN (SELECT Coalesce(Max(id), 0) hranice FROM tabulka WHERE id < 50 AND hodnota < 3) h WHERE t.id < 50 AND t.id > h.hranice ORDER BY t.id LIMIT 1 |
||
Ondra456 Profil * |
#9 · Zasláno: 4. 10. 2012, 20:46:08 · Upravil/a: Ondra456
Kajman:
Ano, toto řešení vypadá že je funkční. Díky moc. Teď se ještě potýkám s hláškou "Table 'comment' was not locked with LOCK TABLES", i když jasně provádím "LOCK TABLES comment WRITE" ale to je asi jiný problém. Předpokládám že se mi to z nějakého důvodu pere s Nette. |
||
Tori Profil |
#10 · Zasláno: 5. 10. 2012, 09:02:40
Joker:
Díky, přehlédla jsem chybu. |
||
Časová prodleva: 12 let
|
0