
SQL - výpis dat
Ahoj,
potřeboval bych poradit, situace je následující:
Eviduji tabulku kategorie:
Create table kategorie (
id_kategorie Integer Not Null auto_increment,
nazev_kategorie Char(30) Not Null,
nadrazene_id_kategorie Integer Null,
Unique (nazev_kategorie),
Primary Key (id_kategorie),
Foreign Key (nadrazene_id_kategorie) References kategorie(id_kategorie) ON DELETE restrict ON UPDATE cascade
) ENGINE='InnoDB' COLLATE 'utf8_czech_ci';
A tabulku produkt, který obsahuje cizí klíč z kategorie, ve které se nachází. Jenže se může nacházet v kategorii, která je nějaké jiné kategorii podřazená (nevím kolika dalším)).
Pro demonstraci máme produkt "plastová", které je v kategorii "levná", která je podřazená kategorii "22 palců", ta je podřazená kategorii "litá kola" a ta je ještě podřazená kategorii "kola".
Potřeboval bych poradit se SELECTEM, který mi vypíše všechny produkty z kategorie "kola" a taktéž všechny produkty ze všech podřazených kateogorií.
Budu vděčný za jakoukoliv radu :) Děkuji
takze urobis to nasledovne:
mam napriklad tabulku kategorie so stlpcami
id_katg, nazov, pid_katg (akoze nadradene ID)
naplnil som si ju datami:
urobil som si pomocnu tabulku vypis, ktora ma totozne 3 polia.
a nakoniec som spravil nasledovnu proceduru:
ked potom spustis proceduru CALL REK_KATG(1); naplni ti tabulku vypis potrebnymi riadkami. Pred opakovanym spustenim je tabulku vypis potrebne premazat.
samozrejme sa to da robit aj bez premazavania nejakym pomocnym ID volania a pod. Toto je len nacrt, staci si ho upravit podla seba. jednoduchsie to asi nebude.
proc by to nemel urobit selectem? Nevim jak v MySQL, ale treba v Oracle bez problemu. Od toho jsou snad - a nevim jak v mysql a ms sql pseudo sloupce jako je level apod.
pretoze mysql a ani ms sql do verzie 2005 nepodporuju rekurzivne subselecty. oracle je trochu na tom lepsie, ale bohuzial v mysql to neurobi. Ide o to, ze on moze mat x urovni nadradenia.
napriklad kategoria s ID = 1 je nadradena kategoriam 2 a 3 a kategoria 2 je nadradena kategorii 4 a 5, kategoria 3 kategoriam 6 a 7 a kategoria 4 nadradena zase 8 a 9....a takto to moze pokracovat. nie je to len twoo levels, ale je to cely niekolkourovnovy strom.
ak teda vyberie kategoriu 2...tak chce polozky spadajuce do kategorii 2, 4, 5, 8 a 9.
ak sa ti na to podari napisat select, tak sa rad priucim, ale moc tomu neverim. v ms sql robim uz par rokov a taketo veci sa jednoducho riesia tabulkovymi funkciami. tie mysql bohuzial nema a pri spiatocnickom zmyslani tvorcov asi ani mat nikdy nebude.
Ok, domluveni - jde to jen na Oracle, ten stromy umi. Ma pseoudoslopce, napriklad LEVEL - coz udava jak moc hluboko to v tom stromu je. - Hezky priklad dole link - pomoci vyplneni mezer podle levelu jde pak veselectovalt i strom :
connect_by.html
no to sa dalo cakat
...oracle je vo vela ohladoch lepsi, skoda, ze sa mi s nim tak zle pracuje....nezvyk 
.
ale jeho silu vidno aj na jednom priklade - pomocou jedneho selectu vyriesit SUDOKU. V MS SQL sa to da tiez, ale len vo verzii 2008. do mysql sa mi to nepodarilo prepisat ani cez procedury a nie to este cez select
inak ten start with je pekna vecicka.
Oracle ma tech moznosti vic, obecne stromy podporuje a je to docela stara funkcionalita, vubec mi nenapadlo, ze jinde to nemaji ;). Clovek si nevazi veci dokud je ma.
Obecne ma Oracle takzvane pseoudosloupce, coz jsou dejmetomu nejake sloupce, kterou jsou ci nejsou ulozene v tabulce ale uzivatl je nedfinoval - tzn, cislo zmeny radku, vnitrni ID, level, poradi radku atd.
Ten level je dobrej, takhle si jde treba vyselektovat tabulku, kde mas v akzdem radku den z celeho roku a to z libovolne tabulky, atd. Tzn muzrd si jednodusse vyselektovat libivolne velkou tabulku s libovolnym poctem radek a naplnit si ji cim chces.
http://technology.amis.nl/blog/6404/oracle-rdbms-1 1gr2-solving-a-sudoku-using-recursive-subquery-fac toring
tu je ten select pre riesenie sudoku. funguje to na baze toho, ze vytvoris string, ktory je akoby vypisanie znamych cisel zo sudoku mriezky zlava doprava zhora dole a na mieste neznamych cisel das medzeru. select potom vrati string, kde prazdne medzery nahradi spravnym cislom :) testoval som to na niekolko stovkach sudoku a vzdy to fungovalo a riesenie to vyplulo v radoch milisekund.
na oracle ma trochu odpudzuje neustale pouzivanie sekvencii kvoli auto number a dost lipnutie na triggeroch, cim sa stava databaza neprehladnejsia, ale to by sa dalo zvyknut. horsie je to s klientom...zatial som mal cest len s Toad for oracle a to bola katastrofa.
bomba ! diky hned si to dam do oblibenych. A samozrejme radne vyzkousim a rozpytvam, cekal jsem ze to bude nejake extremne dlouhej select a ono prd. Kazdopadne slava Oracle, cest ostatnim databazim ;).
Sekvence nepotrebujes pouzivat v triggeru, muzes ronvou insertnout hodnotu z sekvence. A nyni nove na Oracle v poslednim releasu muzes hodnotu sekvence pouzivat kdekoliv, opravdu kdekoliv jako hodnotu, prirazovat to promnenych atd. Neni to primo odpudive, treba nevim jestli MySQL umi cache u sekvence (tzn. kešne si xxx hodnot a pouziva z pameti a nemusi na disk). Problem je, ze kdyz sekvenci neuvedes, tak musis trigger, ale co, staci ji uvect a je to.
Pouzivam SQL Developer - umi toho mnohem mene nez oracle, coz cloveka nuti se nektere veci naucit scriptama a ne klikanim. Obecne vetsinu veci stejne pisu rucne, misto klikani v GUI.
Jinak nevim jak Toad ale SQL Developer umoznuje vlastni filtr nad objektama - tzn, muzes si takovehle triggery pripadne i schovat ;)
taketo funkcie toad mal a mal tych tlacidiel a vysuvacich list tolko, ze na query ostali tak 3-4 riadky textarea :D
souhlas funkci v TOADu je tolik, ze DBA typicky TOADy nemaj radi, tu se někdo uklikne ani nevi jak a sup uz musi obnovovat data. Kolegove je pouzivaji a uplne nadseni nejsou. Naopak SQL Developer (a tusim, ze na MySQL uz taky neco chystaj) je docela fajn.