Jump to content
php.lv forumi

MySQL visu ierakstu select's


fest

Recommended Posts

Rakstot vienu lapu, saskāros ar problēmu, par kuru iepriekš nebija sanācis padomāt:

ir viena tabula ar ierakstiem, un ir otra tabula, kurā ir dati, kas attiecas uz ierakstiem pirmajā tabulā. Otrajā tabulā var būt vairākas rindas, kas attiecas uz vienu rindu no pirmās tabulas (one to many relationship).

Kāds būtu optimālākais veids, kā selektēt no pirmās tabulas visus ierakstus, kopā ar visiem ierakstiem no otrās tabulas. Iepriekš līdzīgiem gadījumiem uz katru rindu no pirmās tabulas izpildīju kveriju pret otro tabulu, taču šajā gadījumā datu apjomi būs stipri lielāki, tāpēc jādomā kaut kas labāks.

Vienīgais, kas pašlaik nāk prātā (izņemot protams pa select'am uz katru pirmās tabulas ierakstu), ir izmantot GROUP_CONCAT() ar kādu viltīgu seperatoru un pēc tam ar PHP sadalīt šo informāciju pa rindām.

Neesmu īpaši pētījis, tāpēc jautāju šeit- varbūt ir kāds efektīvāks risinājums?

Link to comment
Share on other sites

Par JOIN funkcionalitāti zinu. Mani interesē kas nedaudz advancētāks:

Šeit būs piemērs, tam ko gribu panākt:

Tabula 1:

id, title
-----------
1,Title1
2, Title2

Tabula 2:

id,parent_id, data
-------------------
1,1,data1
2,1,data2
3,2,data-n

ar SELECT t1.*, t2.data FROM tabula1 t1 INNER JOIN tabula2 t2 ON t2.parent_id=t1.id

tiek savākts tikai data1.

Es gribētu ar vienu kveriju savākt arī data2 taču tā, lai resultsetā neatkārtotos ieraksti no pirmās tabulas(ar LEFT JOIN atkārtojas), taču šķiet, ka bez GROUP_CONCAT tas nav iespējams.

Kā vispār tiek darīts šādos gadījumos: tiešām selektē ar kādu no outer joiniem un pēc tam apstrādā iegūto resultsetu ar PHP?

Edited by fest
Link to comment
Share on other sites

Nu SQLā AFAIK nekas tāds visām DBVS vairāk vai mazāk kopīgs nav pieejams, tā kā jāskatās kaut kas konkrēti priekš attiecīgās DBVS. Gan jau kāds MySQL guru atbildēs :)

Bet kas, attiecas uz variantiem

1) vai nu LEFT [OUTER] JOIN un tad php konkatenēt bērnu ierakstus vienā stringā kopīgajiem vecāku ierakstiem

2) vai atlasīt n ierakstus galvenajā tabulā un tad n reizes izpildīt vaicājumu uz bērnu tabulu

tad viennozīmīgi variants (1) ir saprātīgais variants :)

 

Gints

Link to comment
Share on other sites

Es tādos gadījumos izmantoju 2 selektus. Pirmajā atlasu datus un id vērtības, pēc tam palaižu otro selektu, kur atlasu vērtības priekš pirmā ar IN. Šim risinājumam ir ierobežojums - ja pirmais selekts atgriezīs baigi daudz rindas, tad viss pasakums varētu sākt mazliet bremzēt. Bet nu parasti pirmajam selektam var uzlikt LIMIT (piemēram, 10 vērtības) un tad otrais ar indeksētu lauku nostrādā diezgan ātri.

 

SELECT id, data FROM TABLE1 LIMIT whatever

SELECT id2, data2 FROM TABLE2 WHERE id IN ($ids)

 

Pēc tam rezultātu saliek kopā ar PHP. Tieši šī daļa ir arī grūtākā, ja grib uzrakstīt eleganti un katram no divu masīvu elementiem iziet cauri tikai vienreiz.

Edited by black
Link to comment
Share on other sites

Paldies par ieteikumiem, taču vēl viens jautājums rodas- kā lai limitē vajadzīgo parent rindu skaitu? Ar vienkāršu LIMIT pie rindām tiks ieskaitītas arī child rindas. Viens variants ir selektēt visu, taču tas būtu baigi neefektīvi, jo rindu skaits jau parent tabulā būs ~10k, kur nu vēl ja pieskaita visas child rindas.

Link to comment
Share on other sites

×
×
  • Create New...