Autor | Zpráva | ||
---|---|---|---|
4ever Profil |
#1 · Zasláno: 12. 9. 2011, 10:15:13
Jak sestavit podmínku když znám id aktuálního záznamu, záznamy jsou řazené podle názvu knihy a chci vybrat buď předcházející záznam nebo následující záznam?
|
||
Tori Profil |
#2 · Zasláno: 12. 9. 2011, 10:20:43
Do FAQ jste se kouknul a nepomohlo?
|
||
4ever Profil |
#3 · Zasláno: 12. 9. 2011, 10:35:16 · Upravil/a: 4ever
Tori:
Na to jsem zapomněl. Nevím jestli je tam pro mě vhodný příklad. V příkladu na daném odkazu je použito znaménko ">". a.sloupecek > b.sloupecek Znamená to, že mohu tohle znaménko použít i na porovnání záznamů u sloupce s názvem knihy? Edit: Stejně ale používám jen jeden sloupec k porovnávání. Takže nevím, ale zdá se mi, že ten příklad není pro mě vhodný |
||
Tori Profil |
#4 · Zasláno: 12. 9. 2011, 10:55:35 · Upravil/a: Tori
4ever:
Zajímavé, porovnávací operátory fungují správně i na řetězce a varování se mi žádné neobjevilo, takže Sloupeček tam je jeden, akorát ta tabulka má dva různé aliasy. Specielně na řetězce by měla být funkce STRCMP |
||
Kajman_ Profil * |
#5 · Zasláno: 12. 9. 2011, 17:03:12
4ever:
„Stejně ale používám jen jeden sloupec k porovnávání.“ To id je v těch příkladech pro jedinečné řazení pro případ, že budou např. dvě knihy pojmenovány 'Pohádky', ale napsali je jiní autoři. Mělo by stačit změnit v příkladu všechna slova 'tabulka' a 'sloupecek'. |
||
e4ever Profil * |
#6 · Zasláno: 14. 9. 2011, 17:56:38
Tak se na ten příklad znovu dívám a zjišťuji, že buď mu vůbec nerozumím, nebo to prostě nemůže fungovat na to co chci. Čistě logicky. Ale snad mi to někdo vysvětlí.
-- předchozí select a.* from tabulka a, tabulka b where b.id = $id and (a.sloupecek < b.sloupecek or (a.sloupecek = b.sloupecek and a.id < b.id)) order by a.sloupecek desc, a.id desc limit 1; Předpokládám, že jde o dvě propojené tabulky, kde a.id a b id. je propojené. je-li podmínka "b.id = $id and ... cokoliv" pak to znamená, že celý výsledek je postavený na aktuálním záznamu a nemůže hledat předchozí záznam. Anebo nechápu rozdíl mezi "b.id = $id and .. cokoliv " a "a.id = $id and .. cokoliv " Pokud smím uvést svůj současný kód, který potřebuju překopat tak, aby nebyl závislý na sloupci a.id ale abych mohl dosadit do podmínky téměř jakýkoliv sloupec, podle kterého chci provést řazení, tak tady je: $order .= "a.`id` "; die($order); if ($args->got['home']==1){ $whererow .= ""; $order = $order."ASC "; } elseif ($args->got['end']==1){ $whererow .= " a.`id`=(select MAX(a.`id`)) AND "; $order = $order."DESC "; } elseif ($args->got['prev']==1){ $whererow .= " a.`id`<".((int) $args->post['rid'])." AND "; $order = $order."DESC "; } elseif ($args->got['reload']==1){ $whererow .= " a.`id`=".((int) $args->post['rid'])." AND "; $order = $order."ASC "; } elseif ($args->got['next']==1){ $whererow .= " a.`id`>".((int) $args->post['rid'])." AND "; $order = $order."ASC "; } $limit = " LIMIT 0,1 "; $all_cols = 'a.`id`, a.`html`, a.`jpg`, a.`path`, a.`cat`, b.`care`, b.`help`'; $order = "ORDER BY ".$order; $where = " $whererow a.`id` = b.`info_id` $order $limit "; $result["result"] = $mysql->query("SELECT_ALL", $all_cols, null, $where); To je teda ten starý kód, který je špatný, protože předpokládá řazení podle id, ale nyní mohu řadit i podle jiného sloupce, který může mít textový formát. |
||
4ever Profil |
#7 · Zasláno: 14. 9. 2011, 17:59:19
($args->got je pole s argumenty, které jsem obdržel přes $_GOT)
|
||
Tori Profil |
#8 · Zasláno: 14. 9. 2011, 19:40:51
4ever:
where b.id = $id and (a.sloupecek < b.sloupecek or (a.sloupecek = b.sloupecek and a.id < b.id)) order by a.sloupecek desc, a.id desc select a.* limit 1 Kdyby se předchozí a následující zjišťovaly podle ID, tak by to určitě šlo jako select * from tabulka where id < $id order by id desc limit 1 e4ever: „potřebuju překopat tak, aby nebyl závislý na sloupci a.id ale abych mohl dosadit do podmínky téměř jakýkoliv sloupec, podle kterého chci provést řazení“ Šlo to zabalit do funkce, která dostane ID aktuálního záznamu, přepínač předchozí/následující, název sloupečku pro řazení (který se zkontroluje proti poli povolených názvů), a volitelně počet řádků, které má vrátit. |
||
Kajman_ Profil * |
#9 · Zasláno: 14. 9. 2011, 20:17:59
Tori:
Přesně tak, je tam dvakrát ta samá tabulka. 4ever: Pokud potřebujete řadit podle sloupců dvou provázaných tabulek, tak bude nejjednodušší vytvořit view, kde budou chtěné sloupce a provázání. Pak stačí udělat tento dotaz z příkladu s oním view. |
||
4ever Profil |
#10 · Zasláno: 14. 9. 2011, 23:24:05
Tori:
„Šlo to zabalit do funkce, která dostane ID aktuálního záznamu, přepínač předchozí/následující, název sloupečku pro řazení (který se zkontroluje proti poli povolených názvů), a volitelně počet řádků, které má vrátit.“ Jestli tě chápu, tak zrovna o něčem takovém jsem teď uvažoval (v javascriptu). Jenže tam těch sloupců pro řazení může být více. Asi by to bylo logičtější než pak pomocí SQL několikrát provádět select pro daný sloupec. V případě že neznám čtyři sloupce aktuálního záznamu, pak 4x používám select na dosazení hodnoty pro jednotlivé sloupce do podmínky WHERE. |
||
4ever Profil |
#11 · Zasláno: 15. 9. 2011, 11:23:31 · Upravil/a: 4ever
Tori:
Ten příklad ale funguje jinak než ty moje tabulky. V tabulce z příkladu se očekává, že v tabulce B je jeden záznam b.id=$id a v tabulce A může k tomuto záznamu existovat nekonečno záznamů pod stejným id. Chápu to správně? A tyto záznamy z tabulky A se mají najít a seřadit. V mojich tabulkách mají a.id a b.id jedinečný klíč, takže k záznamu a.id=$id je vždy jen jeden záznam kde b.id=$id . Takže je to něco úplně jiného. Pro zjednodušení přestaňme mluvit o dvou tabulkách, ale jen o jedné například znám id aktuálního záznamu, produkt, druh, značku, barvu. Existují ještě další sloupce, které chci najít, ale filtrovat a řadit budu podle produkt, druh, značka, barva. Jde o to seřadit zaznamy a z toho pak záznam kde id je větší než aktuální id... nebo menší než aktuální id. |
||
Kajman_ Profil * |
#12 · Zasláno: 15. 9. 2011, 11:32:42
4ever:
„Chápu to správně?“ Stále jste ten příklad nepochopil. V příkadu je dvakrát použita jedna jediná tabulka. Kde "a" a "b" jsou její aliasy. Je to na této stránce psáno již několikrát, čtěte pozorně! Alias "b" je potřeba k nazení hodnoty, podle které se má výběr uskutečnit, když znáte jenom id. Alias "a" se pak použije k nalezení předchozího záznamu. Pokud řadíte podle více sloupců najednou, budou podmínky složitější. |
||
4ever Profil |
#13 · Zasláno: 15. 9. 2011, 11:34:58 · Upravil/a: 4ever
Kajman:
Omlouvám se, ale když to u toho příkladu není přímo napsáno a mezi návštěvami tohoto vlákna dělám docela dlouhé mezery tak trochu pozapomínám o čem se psalo. Jakým způsobem mám vytvořit ty dva různé aliasy pro jednu a tu samou tabulku? Takto? SELECT * FROM tabulka1 AS a, tabulka1 AS aa, tabulka2 AS b ....? |
||
4ever Profil |
#14 · Zasláno: 15. 9. 2011, 12:03:21
Tak to zkouším:
SELECT * FROM basic AS a,basic AS x,detaily AS b WHERE x.`id` == 34 AND (a.`cat` < x.`cat` OR (a.`cat` = x.`cat` AND a.id < x.id)) a.`id` = b.`basic_id` ORDER BY a.`cat` DESC LIMIT 0,1 hlásí There seems to be an error in your SQL query. The MySQL server error output below, if there is any, may also help you in diagnosing the problem ERROR: Unknown Punctuation String @ 66 STR: == SQL: SELECT * FROM basic AS a,basic AS x,detaily AS b WHERE a.`id` == 34 AND (x.`cat` < a.`cat` OR (x.`cat` = a.`cat` AND x.id < a.id)) x.`id` = b.`basic_id` ORDER BY x.`cat` DESC LIMIT 0,1 SQL query: Documentation SELECT * FROM basic AS a,basic AS x,detaily AS b WHERE a.`id` == 34 AND (x.`cat` < a.`cat` OR (x.`cat` = a.`cat` AND x.id < a.id)) x.`id` = b.`basic_id` ORDER BY x.`cat` DESC LIMIT 0,1 MySQL said: Documentation #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '== 34 AND (x.`cat` < a.`cat` OR (x.`cat` = a.`cat` AND x.id < a.id)) ' at line 1 tabulku b už mám rezervovanou, takže jsem zkusil místo b dát x |
||
Kajman_ Profil * |
#15 · Zasláno: 15. 9. 2011, 13:06:27
A proč nevytvoříte view viz. příspěvek číslo [#9]?
|
||
4ever Profil |
#16 · Zasláno: 15. 9. 2011, 13:08:38
Kajman:
View? Nevím co tím myslíte. Co znamená "ERROR: Unknown Punctuation String @ 66"? |
||
Kajman_ Profil * |
#17 · Zasláno: 15. 9. 2011, 13:35:10
4ever:
„View? Nevím co tím myslíte.“ Myslím view. create view ukazka_view as select a.`id`, a.`html`, a.`jpg`, a.`path`, a.`cat`, b.`care`, b.`help` from basic a join detaily b on a.`id` = b.`info_id` To pak jednoduše použijete v dotaze z příkladu. -- předchozí select a.* from ukazka_view a, ukazka_view b where b.id = 34 and (a.`cat` < b.`cat` or (a.`cat` = b.`cat` and a.id < b.id)) order by a.`cat` desc, a.id desc limit 1; Jinak byste se tam musel plahočit s dvakrát dvěma tabulkami, což bych nedoporučoval, když dělá takové problémy i dvakrát jedna tabulka. |
||
4ever Profil |
#18 · Zasláno: 15. 9. 2011, 13:59:57 · Upravil/a: 4ever
No jo, ale to pak data nebudou pocházet z tabulky, ve které edituju data, ale z tabulky ukazka_view. Tím pádem se mi nenačtou aktuální data. Ty data se pořád mění, protože s nima pracuju (edituju je).
PS: Zápis tabulka a , tabulka b taky neznám. To platí jenom pro ty náhledy? Nebo to mohu použít u běžné tabulky? Teď jsem přepsal dotaz tabulka1 AS a , tabulka2 AS x, tabulka3 AS b na tabulka1 a , tabulka2 x, tabulka3 b A píše to skoro stejnou chybu jako před tím ERROR: Unknown Punctuation String @ 354 STR: == .... #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '== 34 AND (a.`cat` < x.`cat` OR (a.`cat` = x.`cat` AND a.id < x.id)) ' at line 1 ... Takže to nejede ani s AS ani bez AS |
||
Kajman_ Profil * |
#19 · Zasláno: 15. 9. 2011, 14:06:32
4ever:
„No jo, ale to pak data nebudou pocházet z tabulky, ve které edituju data“ Ale budou! Co si přečíst ten odkaz nebo alespoň to vyzkoušet? |
||
4ever Profil |
#20 · Zasláno: 15. 9. 2011, 14:11:27 · Upravil/a: 4ever
Kajman:
Právě že jsem ho vyzkoušel a když v phpmyadminu kliknu na tu tabulku/náhled ukazka_view tak tam vidím výběr těch dat co mám v původní tabulce. Tak jsem myslel, že to jsou vlastně jen data vyexportovaná do jiné tabulky. Edit: Tak asi je to něco jiného, když tu "tabulku" nejde editovat. Edit2: Tak jsem se dočetl, že s těmi pohledy to není až tak slavné, co se týče výkonu. Nicméně nevím jak jinak to napsat, abych mohl filtrovat a zeřazovat data a najít předchozí/následující/první/poslední záznam, bez pohledů... |
||
4ever Profil |
#21 · Zasláno: 15. 9. 2011, 14:28:36 · Upravil/a: 4ever
A když se pokusím vytvořit náhled:
CREATE VIEW ukazka2_view AS SELECT a. * , b. * FROM info a JOIN detaily b ON a.`id` = b.`info_id` #1060 - Duplicate column name 'id' To píše asi proto, že obě tabulky mají stejný sloupec id. Chtěl jsem vybrat všechny sloupce Edit: Ještě jeden dotaz. Ten příklad z FAQ nejdříve řadí data (a podle čeho) a pak teprve najde předchozí/následující záznam? No já se ptám, protože zatím jsem to ještě nerozjel. Jestli řadí data podle VIEW tak to je špatné, protože chci nejdříve seřadit podle toho jak to nadefinoval uživatel a pak teprve najít předchozí/následující záznam. |
||
Kajman_ Profil * |
#22 · Zasláno: 15. 9. 2011, 16:33:42
4ever:
„To píše asi proto, že obě tabulky mají stejný sloupec id. Chtěl jsem vybrat všechny sloupce“ Tak klidně vyberte všechny sloupce, ale určete jim jedinečné identifikátory. Viz. manuál: Views must have unique column names with no duplicates, just like base tables. By default, the names of the columns retrieved by the SELECT statement are used for the view column names. To define explicit names for the view columns, the optional column_list clause can be given as a list of comma-separated identifiers. The number of names in column_list must be the same as the number of columns retrieved by the SELECT statement. „protože chci nejdříve seřadit podle toho jak to nadefinoval uživatel a pak teprve najít předchozí/následující záznam.“ Místo slova sloupecek ve faq (nebo místo `cat` v [#17]) dáte název sloupečku, podle kterého chce uživatel řadit. Co je na tom těžkého pochopit? Už to tu bylo psáno několikrát! |
||
Časová prodleva: 5 dní
|
|||
Igor Profil |
#23 · Zasláno: 20. 9. 2011, 10:12:21 · Upravil/a: Igor
Dnes jsem se dostal k tomu, abych to dodělal. Duplicitní sloupce a chyby syntaxe jsem odstranil.
Zkouším tedy tento příkaz: SELECT x . * FROM ukazka_view x, ukazka_view y WHERE x.`id` =10 AND ( x.`cat` < y.`cat` OR ( x.`cat` = y.`cat` AND x.`id` < y.`id` ) ) ORDER BY x.`id` DESC LIMIT 0 , 1 kde x odpovídá a; y odpovídá b. Vrací mi to pouze aktuální záznam tedy id=10. |
||
4ever Profil |
#24 · Zasláno: 20. 9. 2011, 10:13:29
Tedy to bylo ode mě.
|
||
Kajman_ Profil * |
#25 · Zasláno: 20. 9. 2011, 10:32:16
Znovu se pozorně podívejte na příklad! Má tam být přeci
y.`id` =10 |
||
4ever Profil |
#26 · Zasláno: 20. 9. 2011, 11:40:31 · Upravil/a: 4ever
Tak nevím. Chová se to nějak divně. "Následující" asi funguje správně. Klikám asi 100x a projdu postupně záznamy, které jsou seřazené podle sloupce cat. Když pak kliknu na Předchozí, tak jsem na id=58 a pak kliknu ještě jednou na Předchozí a jsem na id=13 a konec dál to nejde. Což znamená, že když dám vybrat Předchozí tak to přeskočí mnoho záznamů.
Predchozi: SELECT x.* FROM ukazka_view x, ukazka_view y WHERE y.`id` = 13 AND (x.`cat` < y.`cat` OR (x.`cat` = y.`cat` AND x.`id` < y.`id`)) ORDER BY x.`cat` DESC LIMIT 0,1 Nasledujici SELECT x.* FROM ukazka_view x, ukazka_view y WHERE y.`id` = 13 AND (x.`cat` > y.`cat` OR (x.`cat` = y.`cat` AND x.`id` > y.`id`)) ORDER BY x.`cat` ASC LIMIT 0,1 id=13 je první id, které se zobrazí, když dám seřadit sloupec podle `cat` Takže Když klikám na následující, posouvá se po jednotlivých id, ale když klikám na předchozí, posouvá se po kategoriích (cat). Přitom mi ty dva příkazy připadají skoro stejné, jen je rozdíl ve dvou operátorech. |
||
Kajman_ Profil * |
#27 · Zasláno: 20. 9. 2011, 13:02:07
Tohle vlákno se asi bude řešit forever :-( Nechápu, že dokážete v takovém krátkém a jednoduchém dotaze nasekat tolik chyb.
Znovu se pozorně podívejte na příklad! Má tam být přeci ORDER BY x.`cat` DESC, x.`id` DESC ORDER BY x.`cat` ASC, x.`id` ASC Nutnost id je zmíněna i v příspěvku [#5] |
||
4ever Profil |
#28 · Zasláno: 20. 9. 2011, 15:53:54 · Upravil/a: 4ever
Kajman_:
Nj, snažil jsem se to nějak předělat, ale nenapadlo mě že by příčina mohla být v id. Díky, už to funguje. Bylo by možné ještě přidat instrukce jak napsat požadavek na První a Poslední záznam podle stejného principu řazení (prostě nějak nechápu tu logiku, protože s funkcemi MIN a MAX mi to nejde)? Jestli je to problém založím nové vlákno, jinak tohle je poslední dotaz ohledně řazení v tomto projektu. |
||
Kajman_ Profil * |
#29 · Zasláno: 20. 9. 2011, 18:36:50
-- prvni SELECT x.* FROM ukazka_view x ORDER BY x.`cat` ASC, x.`id` ASC LIMIT 1 -- posledni SELECT x.* FROM ukazka_view x ORDER BY x.`cat` DESC, x.`id` DESC LIMIT 1 |
||
4ever Profil |
#30 · Zasláno: 21. 9. 2011, 22:20:01 · Upravil/a: 4ever
Kajman:
Díky za pomoc. Mezitím jsem zkoušel sestavit příkaz na výběr Předchozího a Následujícího s více sloupci k seřazení. Přijde mi, že to nemůže na více sloupců spolehlivě fungovat, protože podmínka x.id < y.id pokud id=1 bude vždy false. Už to mám sestavený jako takovou navigaci, která funguje do té doby dokud nenajedeš na id=1. Pak Předchozí ani Následující nebude fungovat. Na id=1 se dostat jedině pomocí výběru Prvního nebo Posledního nebo nějak jinak. Prakticky to ale rozdělí tu navigaci na sekvenci čísel od n až po x-1 a x+1 až m... kde x=id=1, n=id prvního řádku, m=id posledního řádku |
||
Téma pokračuje na další straně.
|
0