« 1 2 »
Autor Zpráva
4ever
Profil
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
Do FAQ jste se kouknul a nepomohlo?
4ever
Profil
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
4ever:
Zajímavé, porovnávací operátory fungují správně i na řetězce a varování se mi žádné neobjevilo, takže asi to je ok. Edit: Manuál: „These operations work for both numbers and strings. Strings are automatically converted to numbers and numbers to strings as necessary. Akorát musíte mít správně nastavené porovnávání pro ten sloupec nebo tabulku (např. utf8_czech_ci), anebo ho doplnit do dotazu.
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 *
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 *
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
($args->got je pole s argumenty, které jsem obdržel přes $_GOT)
Tori
Profil
4ever:
where  b.id = $id
Najde aktuální záznam,
and (a.sloupecek < b.sloupecek or (a.sloupecek = b.sloupecek and a.id < b.id))
najde všechny pod ním,
order  by a.sloupecek desc, a.id desc
seřadí je
select a.*
vybere pouze ty, které jsou před aktuálním záznamem
limit  1
a z nich jen první = první před aktuálním.
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
Ale jelikož se aktuální záznam hledá podle jednoho sloupce a předchozí/násl. podle jiného, tak je to udělané takhle, se dvěma aliasy pro stejnou tabulku. Aspoň teda tak jsem to pochopila.

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 *
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
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
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 *
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
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
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 *
A proč nevytvoříte view viz. příspěvek číslo [#9]?
4ever
Profil
Kajman:
View? Nevím co tím myslíte. Co znamená "ERROR: Unknown Punctuation String @ 66"?
Kajman_
Profil *
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
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 *
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
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
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 *
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!
Igor
Profil
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
Tedy to bylo ode mě.
Kajman_
Profil *
Znovu se pozorně podívejte na příklad! Má tam být přeci
y.`id` =10
4ever
Profil
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 *
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
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 *
-- 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
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
« 1 2 »

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0