Jump to content
php.lv forumi

IF/ELSE konstrukcija LEFT JOIN kverijā


404

Recommended Posts

Š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 by 404
Link to comment
Share on other sites

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 by ABU
Link to comment
Share on other sites

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 :)

Link to comment
Share on other sites

Šā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   

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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.

 

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...