Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailem 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

Předmět Autor Datum
selectom to neurobis a uz duplom nie v mysql....v MS SQL by sa to dalo riesit rekurzivnou tabulkovou…
wam_Spider007 27.03.2011 20:07
wam_Spider007
takze urobis to nasledovne: mam napriklad tabulku kategorie so stlpcami id_katg, nazov, pid_katg (a…
wam_Spider007 27.03.2011 20:25
wam_Spider007
proc by to nemel urobit selectem? Nevim jak v MySQL, ale treba v Oracle bez problemu. Od toho jsou s…
AZOR 27.03.2011 20:31
AZOR
pretoze mysql a ani ms sql do verzie 2005 nepodporuju rekurzivne subselecty. oracle je trochu na tom…
wam_Spider007 27.03.2011 20:36
wam_Spider007
ja nevim v cem to potřebuje, znam jen Oracle, MsSQL a MySQL jdou mimo mne. Pokud tu rikas, ze to MyS…
AZOR 27.03.2011 20:49
AZOR
Ok, domluveni - jde to jen na Oracle, ten stromy umi. Ma pseoudoslopce, napriklad LEVEL - coz udava…
AZOR 27.03.2011 20:51
AZOR
no to sa dalo cakat :-) ...oracle je vo vela ohladoch lepsi, skoda, ze sa mi s nim tak zle pracuje..…
wam_Spider007 27.03.2011 21:05
wam_Spider007
:-) kde mas to sudoku? to by mi docela dost zajimalo, diky. Oracle ma tech moznosti vic, obecne str…
AZOR 27.03.2011 21:15
AZOR
http://technology.amis.nl/blog/6404/oracle-rdbms-1 1gr2-solving-a-sudoku-using-recursive-subquery-fa…
wam_Spider007 27.03.2011 21:24
wam_Spider007
bomba ! diky hned si to dam do oblibenych. A samozrejme radne vyzkousim a rozpytvam, cekal jsem ze t…
AZOR 27.03.2011 21:37
AZOR
Jinak nevim jak Toad ale SQL Developer umoznuje vlastni filtr nad objektama - tzn, muzes si takovehl…
AZOR 27.03.2011 21:38
AZOR
taketo funkcie toad mal a mal tych tlacidiel a vysuvacich list tolko, ze na query ostali tak 3-4 ria…
wam_Spider007 27.03.2011 21:53
wam_Spider007
souhlas funkci v TOADu je tolik, ze DBA typicky TOADy nemaj radi, tu se někdo uklikne ani nevi jak a… poslední
AZOR 28.03.2011 01:00
AZOR
taktiez pouzivam na vsetko script, pri mysql cisto len terminal, pri MS SQL ten ich management, ale…
wam_Spider007 27.03.2011 21:52
wam_Spider007
Oprasit nebo oprášit? Pozor na diakritiku... :-D
host 27.03.2011 21:54
host
Uplne netusim o co mas zajem, ale predpokladam ze o definici vlastni promene a vraceni hodnoty do ni…
AZOR 28.03.2011 00:54
AZOR
Jo, promiňte, nenapsal jsem to, jedná se o MySQL. Vyzkouším ten tvůj kód, i když něco z toho už jde…
LordUfo 27.03.2011 20:57
LordUfo
To je jedno jestli vis kolik je maximum podrazenosti, ne? Bud si fetchnes (nactes) do promene to max…
AZOR 27.03.2011 21:02
AZOR
ze ide o mysql sa da zistit hned z dvoch veci "auto_increment" a "Engine" - tuto zhovadilost ma len…
wam_Spider007 27.03.2011 21:02
wam_Spider007
To vypadá dobře, rozhodně to chápu líp, než ten návod předtím :) Vyzkouším, jeste jednou thx oběma :…
LordUfo 27.03.2011 21:16
LordUfo

takze urobis to nasledovne:

mam napriklad tabulku kategorie so stlpcami
id_katg, nazov, pid_katg (akoze nadradene ID)

naplnil som si ju datami:

+---------+----------+----------+
| id_katg | nazov    | pid_katg |
+---------+----------+----------+
|       1 | auto     |     NULL |
|       2 | 3 dv     |        1 |
|       3 | 5 dv     |        1 |
|       4 | hatchbag |        2 |
+---------+----------+----------+

urobil som si pomocnu tabulku vypis, ktora ma totozne 3 polia.

a nakoniec som spravil nasledovnu proceduru:

CREATE PROCEDURE REK_KATG (IN _pid_katg int)
BEGIN
	DECLARE _id_katg INT;
	DECLARE XCUR CURSOR FOR SELECT id_katg FROM kategoria WHERE pid_katg = _pid_katg;
	
	INSERT INTO VYPIS
	SELECT id_katg, nazov, pid_katg FROM kategoria where id_katg = _pid_katg;
	
	OPEN XCUR;

	BEGIN
	DECLARE EXIT HANDLER FOR NOT FOUND BEGIN END;
	LOOP
	FETCH XCUR INTO _id_katg;
	
		CALL REK_KATG(_id_katg);
	
	END LOOP;
	END;
	
	CLOSE XCUR;
END

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.

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.

ja nevim v cem to potřebuje, znam jen Oracle, MsSQL a MySQL jdou mimo mne. Pokud tu rikas, ze to MySQL neumi a MSQL , tak neni duvod Ti neverit.

Nicmene z toho co napsal to vypada na MySQL. Kazdopadne jsem zagooglil a vypada to, ze to MySQL neumi. Jak se postupuje dale v tomhle pripada na urovni DB MYSQL netusim. Kazdopadne podle Google to vypada, ze to minimalne slibovali a jedine co umi ja ta funkce : bug.php

V Oracle pak neco takoveho. Je to jen nastrel, prave jsem vylezl z vany a nemam tu Oracle a navic je mi zima na koule ;)

SELECT * FROM produkt WHERE id_kategorie IN (
SELECT id_kategorie
FROM kategorie
START WITH kategorie=kolo
CONNECT BY PRIOR kategorie_id = nadrazene_id_kategorie);

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 :-D.

inak ten start with je pekna vecicka.

:-) kde mas to sudoku? to by mi docela dost zajimalo, diky.

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.

taktiez pouzivam na vsetko script, pri mysql cisto len terminal, pri MS SQL ten ich management, ale nedizajnujem views ani tabulky, klepem to rucne. klikacie GUI vacsinou generuje prasaciny (sry za vyraz).

tak mysql a ani ms sql sekvencie nepoznaju. co som niekde cital, tak k mysql dokonca existuje dokumentacia limitov - teda dokumentacia popisujuca co vsetko mysql nepodporuje, alebo nemoze urobit :-D

a este taka vec - ako je to s testovanim procedur. v MS SQL si vytvorim proceduru a potom len v query ju spustim aj s pripadnym vypisom vystupnych parametrov napriklad:

-- premenna pre vystupnu hodnotu
DECLARE @VYSTUP INT

EXEC PROCEDURA 'test', 1, @VYSTUP OUTPUT

SELECT @VYSTUP

takyto postup ked som chcel v TOADe urobit, tak to neslo a muselo sa to nejak komplikovane. Pokial to v tom SQL Developeri ide jednoduchsie, tak to bude potom aj stat za to skusit ten oracle viac oprasit.

Uplne netusim o co mas zajem, ale predpokladam ze o definici vlastni promene a vraceni hodnoty do ni a jeji vypis. Ano, to Oracle umi - uzivatelska promena, misto DECLARE, se ale pise DEFINE a misto @ se pouziva &, pouziti podobne. Tedy ano, umime.

Pokud to ma smysl, Oracle to umi. Tzn. tak trosku jako Marta Jandová - nejlepší 8-)

Jo, promiňte, nenapsal jsem to, jedná se o MySQL. Vyzkouším ten tvůj kód, i když něco z toho už jde mimo mě, nějaký DECLARE jsem ještě nikdy nedělal. Ale dík, vyzkouším to.

UPDATE: mimochodem, když bych věděl, že třeba maximum podřazeností je 5 a napsal nějaký for cyklus opakující SELECT, tak by to jít mělo, ne?

To je jedno jestli vis kolik je maximum podrazenosti, ne? Bud si fetchnes (nactes) do promene to maximum a pokud to nepujde tak misto cyklu FOR pouzejes cyklus WHILE (doufam, ze MySQL umi :-D)

Jinak v tom linku na bug.mysql je taky nějaká procka, která by to měla umět, co jsem postřehl.

ze ide o mysql sa da zistit hned z dvoch veci "auto_increment" a "Engine" - tuto zhovadilost ma len mysql. :)

inak este je jedno riesenie, vytvorit si nejaku mapovaciu tabulku s dvoma stlpcami, kde budu ku kazdej kategorii jej nadradene kategoria a to nie len tie priamo nadriadene, ale aj ich nadriadene.
napriklad kategoria 2 ja podradena kategorii 3 a ta je zase podradena kategorii 4

mal by si potom v tabulke dvojica

2 - 2
2 - 3
2 - 4
3 - 3
3 - 4
4 - 4

potom by si vedel na zaklade cisla kategoria vytiahnut vsetky podradene. toto naplnanie mapovacej tabulky by si osefoval v aplikacii alebo nejakou procedurou.

Zpět do poradny Odpovědět na původní otázku Nahoru