404 Posted May 27, 2010 Report Share Posted May 27, 2010 (edited) Šobrīd ir šāds te MySQL kverijs(saīsinātā variantā),kas ielasa saita kategoriju un sekciju datus: SELECT c.id AS c_id, c.access AS c_access, c.name AS c_name, c.subtable AS c_subtable, s.id AS s_id, s.parent_id AS s_parent_id, s.access AS s_access, s.name AS s_name FROM categories AS c LEFT JOIN sections AS s ON s.parent_id = c.id ORDER BY c.order_id,s.order_id Viss strādā,bet tā kā ir arī daļa datu,kas pieder pie kategorijas,bet neglabājas tabulā 'sections',tad kategoriju tabulas laukā ir uzdots 'subtable' kā alternatīvā tabula,no kuras lasīt datus ja tāda ir uzdota(ja lauks nav tukšs).Lai nebūtu jātaisa atsevišķs pieprasījums,tad mēģinu iedabūt kverijā if/else pārbaudi.Tas ko gribētu panākt būtu apmēram šādi: IF (c.subtable NOT NULL) LEFT JOIN c.subtable AS s ELSE LEFT JOIN sections AS s ENDIF Bet tā kā nav pieredzes ar šāda veida konstrukcijām,tad mēģinot visādi izdevās panākt vienīgi sintakses kļūdu.Kā būtu pareizi būvēt šādu nosacījumu? Edited May 27, 2010 by 404 Quote Link to comment Share on other sites More sharing options...
ABU Posted May 27, 2010 Report Share Posted May 27, 2010 (edited) Normālā veidā SQL pieprasījumos nav iespējams ievietot IF/ELSE pārbaudes. It īpaši vēl tabulas. Labākais variants ir SQL pieprasījumu sataisīt stringā un tad ar savu IF/ELSE norādi vajadzīgo tabulu. Ja grib visu ielikt vienā SQL pieprasījumā, tad var izmantot šādu variantu: SELECT c.id AS c_id, c.access AS c_access, c.name AS c_name, c.subtable AS c_subtable, nvl(s1.id,s2.id) AS s_id, nvl(s1.parent_id,s2.parent_id) AS s_parent_id, nvl(s1.access,s2.access) AS s_access, nvl(s1.name,s2.name) AS s_name FROM categories AS c LEFT JOIN sections AS s1 ON s1.parent_id = c.id LEFT JOIN c.subtable AS s2 ON s2.parent_id = c.id ORDER BY c.order_id,nvl(s1.order_id,s2.order_id) Tikai šajā variantā, ja tabulā sections būs atbilstoši ieraksti, tad tie arī tiks attēloti. Ja nebūs, tad tiks attēloti atbilstošie ieraksti no c.subtable tabulas. Edited May 27, 2010 by ABU Quote Link to comment Share on other sites More sharing options...
404 Posted May 27, 2010 Author Report Share Posted May 27, 2010 Tas variants derētu,ja būtu pāris kategorijas ar iepriekš zināmu apakštabulu.Bet tā kā viņu ir pietiekami,tad katrai kategorijai formēt savu sql stringu ar vajadzīgo joinu nebūs īsti prātīgi laikam.Bet ja nevarēs savādāk,tad kaut ko uz to pusi jau būs jādomā laikam :) Quote Link to comment Share on other sites More sharing options...
ABU Posted May 27, 2010 Report Share Posted May 27, 2010 Nepaspēju laicīgi saglabāt savu laboto rakstu. Tur esmu papildinājis savu tekstu. Quote Link to comment Share on other sites More sharing options...
404 Posted May 27, 2010 Author Report Share Posted May 27, 2010 Šādi varētu būt ok,bet nu ir cita kļūda: Table 'c.subtable' doesn't exist.Tagad nevaru saprast,vai kverijā netiek viņa atrasta jeb man kaut kas ar db ne tā.Cik saprotu,tad nvl iekš mysql jāraksta kā IFNULL,bet arī tā neiet.Šis piemērs uzvedināja uz vēl vienu domu.Šādu nosacījumu nav iespējams kaut kā iedabūt kverijā? FROM categories AS c LEFT JOIN IFNULL('c.subtable','sections') AS s Quote Link to comment Share on other sites More sharing options...
Gints Plivna Posted May 27, 2010 Report Share Posted May 27, 2010 Tas ko tu gribi vienkārši nav iespējams. SQL teikuma parsēšanas brīdī visiem objektiem ir jābūt zināmiem un tur nekādus mainīgos (kas reāli būs dati no tabulas) izmantot nevar. Vai nu pasākums jātaisa 2 soļos, vai arī jāpārdomā db shēma, kas šai gadījumā nav īsti laba. IR ok glabāt šur tur kādreiz metadatus, lai dinamiski kaut ko varētu uzģenerēt, bet ir jāapzinās sekas - tas 1kārt 100% prasa dinamisko SQL, rada potenciāli daudz lielākus kļūdu iespējas un arī no ātrdarbības viedokļa nav tas labākais risinājums. Gints Plivna http://datubazes.wordpress.com Quote Link to comment Share on other sites More sharing options...
404 Posted May 27, 2010 Author Report Share Posted May 27, 2010 Nu skaidrs.Bija šis tas lasīts par if/else iespēju,bet nu ir skaidrs,kāpēc tieši šādam risinājumam nekur piemērus atrast neizdevās :) Paldies par atbildēm,un pārdomāšu iespējas vai nu pirms kverija saformēt vajadzīgo sql stringu,vai savādāk organizēt tabulas.Labi ka saits tikai izstrādes stadijā.Variantus var diezgan brīvi mainīt. Quote Link to comment Share on other sites More sharing options...
ABU Posted May 28, 2010 Report Share Posted May 28, 2010 ... kļūda: Table 'c.subtable' doesn't exist... Tas nozīmē, ka tev nav šādas tabulas c.subtable. Ieraksti precīzu tabulas nosaukumu un tad visam jāstrādā. Bet, kā jau Gints rakstīja, labāk ir pārdomāt DB struktūru, lai viena laukā esošo datu kodifikatori neatrastos daāžadās tabulās. Quote Link to comment Share on other sites More sharing options...
404 Posted May 28, 2010 Author Report Share Posted May 28, 2010 Tur jau tie joki,ka gan tabula tāda ir,gan viņas nosaukums pareizs,bet vienalga neatrod. Db struktūra šobrīd ir pēc principa kategorijas->sekcijas->subsekcijas.Pašas idejas pamatā,kāpēc gribēju šādu kveriju ir tas,ka tematiski atšķirīgas sadaļas(piemēram rakstus) lai nebūtu viss vienā putrā iekš 'sections',tad iznest ārā atsevišķās tabulās,bet masīvā joprojām ielasīt tāpat kā visas sadaļas,lai apstrādes pusē nekas nemainītos.Tad arī radās tā ideja dinamiski uzreiz kverijā izvēlēties un piedžoinot vai nu vienu vai otru.Ja tā nav iespējams,tad nāksies domāt ko citu.Viens no variantiem,kas nāk prātā-lasīt tikai kategorijas un ciklā iet cauri masīvam, taisot pieprasījumus uz apakštabulām.Tas laikam būs visai bremzīgs risinājums.Kādi vēl varētu būt varianti? Saformēt pirms kverija sql stringu varētu,ja būtu zināms,kāda apakštabula kurai kategorijai būs vajadzīga.Bet tas kļūst zināms tikai kverija laikā :D Quote Link to comment Share on other sites More sharing options...
ABU Posted May 28, 2010 Report Share Posted May 28, 2010 pēc tava pirmā SQL pieprasījuma sanāk, ka tev visu tabulu nosaukumi atrodas tabulas categories laukā subtables. Un tad tiešām ar vienu SQL pieprasījumu to nebūs iespējams izdarīt. To tev vajadzēs apstrādāt dinamiski (tā kā tu pats rakstīji pēdējā postā): 1. nolasīt visus datus no tabulas categories; 2. nolasīt vajadzīgo ierakstu no tabulas, kas norādītā laukā subtables. Es uzskatu, ka šāds risinājums ir galīgi garām. Labāk jau visus kodifikatorus (sekcijas un subsekcijas) turēt vienā vai 2 atsevišķās tabulās, nevis šāda veidā, kad no tabulas lauka taisa pieprasījumu uz citu tabulu. Ieteiktu tomēr pārdomāt savas DB tabulu struktūru. Quote Link to comment Share on other sites More sharing options...
404 Posted May 28, 2010 Author Report Share Posted May 28, 2010 Visu tabulu nosaukumi neglabājas iekš 'subtable' lauka.Defaultā tas ir NULL un tieši to arī prasījās pārbaudīt,vai lauks kaut ko satur.Ja jā,tad tur atrodas alternatīvā apakštabula,un džoinot no viņas.Ja nē,tad no 'sections'.Protams nav problēmu visu,kas vajadzīgs glabāt vienā 'sections',bet tad viņa sanāks kā pamatīga tabula,kurā vienā rosolā būs autorizācija,raksti,aptaujas un viss pārējais,kas vien ir zem saita kategorijām.Droši vien tas arī nav slikts variants,un lasīts arī par pieeju,kad vispār kategorijas,sekcijas,subsekcijas glabā visas 1 tabulā,kuru rekursīvi nolasa.Katrai metodei savi trūkumi.Kaut kā loģiskāk likās tomēr sagrupēt par spīti čakaram ar sasaistīšanu.Jeb tomēr jāiet uz pāris tabulu variantu un miers? Quote Link to comment Share on other sites More sharing options...
ABU Posted May 29, 2010 Report Share Posted May 29, 2010 Mans priekšlikums - sataisi nortmālas kodifikatoru tabulas un normālā veidā tās sasaisti savā strapā. Var arī izmantot variantu, kā pats aprakstīji - katram rakstam atrod tabulu un tad to ielasīt vai arī izanalizēt, kādas tabulas vajag, tad tās savākt masīvā. Bet atceries, ka uz maziem datiem tas varētu arī ātri strādāt, bet, kad datu apjoms ļoti pieaugs, tad šādas datu atlasīšanas katram rakstam/ viltīgas tabulu ananlīzes būs ļoti lēnas un nelietderīgas. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.