Jump to content
php.lv forumi

pedejais ieraksts par kviti


localhero

Recommended Posts

localhero, to viegli pārrakstīt, neatgriežot pēc max_id, bet `ORDER DESC LIMIT 1` :) /tas pats, tikai pēc jebkura lauka/-iem/

bubu, a nebūs tā, ka iekš sub0-selekta @row neresetosies, to biš ti kun tā nebūs iespēja atfiltrēt pēc WHERE sub_row_num = 0

Edited by Delfins
Link to comment
Share on other sites

Kaut kā šitā (mazliet piekoriģēts alekseja variants) izskatās ka ir +- OK

 

SQL> ed
Wrote file afiedt.buf

 1  select k.id, k.nosaukums, d.id, d.kvits_id, d.darbiba
 2  FROM kvitis k LEFT JOIN darbibas d ON k.id = d.kvits_id
 3  WHERE d.id IN (
 4	SELECT max(d2.id) FROM darbibas d2
 5	GROUP BY kvits_id)
 6* OR d.id IS NULL
SQL> /

	ID NOSAUKUMS					ID   KVITS_ID DARBIBA
---------- -------------------- ---------- ---------- --------
	 1 nos1						  4		  1 atgr
	 3 nos3						  5		  3 sav
	 2 nos2

 

Ar row_number() tas būtu šitā:

SQL> ed
Wrote file afiedt.buf

 1  select nosaukums, id, kvits_id, darbiba
 2  from (
 3	select k.nosaukums, d.id, d.kvits_id, d.darbiba,
 4	row_number() over (partition by d.kvits_id order by d.id desc) rn
 5	FROM kvitis k LEFT JOIN darbibas d ON k.id = d.kvits_id
 6  )
 7* where rn = 1
SQL> /

NOSAUKUMS					ID   KVITS_ID DARBIBA
-------------------- ---------- ---------- --------------------
nos1						  4		  1 atgr
nos3						  5		  3 sav
nos2

Link to comment
Share on other sites

Gints Plivna: to row_number ir viegli "simulēt" pašam: http://forums.mysql.com/read.php?10,36490,36511

Pliku row_number varbūt var, bet ar partition by, kas reseto to numberi uz 0 pie katras nākošās vērtības, kas ir iekš partition by klauzas jādomā, ka būs grūti. Kaut gan es neko no MySQL nejēdzu, tā kā varbūt var :)

 

Bet anyway analītiskās f-jas rullē nemērīgi (tai bāzēs kur tās ir protams :)

Link to comment
Share on other sites

Gint, bet vai nav tā, ka:

SELECT max(d2.id) FROM darbibas d2 GROUP BY kvits_id

Atgriezīs vienmēr maksimālo no visiem darbibas.id neskatoties uz to, ka mums interesē tikai tie, kuriem d2.kvits_id = k.id? Vai arī šo lietu garantē group by?

Un kura kvits_id vērtība tiks izmantota GROUP BY klauzā? d.kvits_id vai d2.kvits_id?

Link to comment
Share on other sites

Gints Plivna, nākošreiz, kad atbildi pievērs uzmanību bāzei. Tas, ka iekš Oracle var praktiski jebko, visi zin. Viņam vajag MySQL risinājumu.

Nu neies viņš tak mainīt MySQL uz Oracle.

 

Nu es jau iedevu arī mazliet pakoriģētu subselect variantu, kas strādā arī uz MySQL ;)

Link to comment
Share on other sites

Gint, bet vai nav tā, ka:

SELECT max(d2.id) FROM darbibas d2 GROUP BY kvits_id

Atgriezīs vienmēr maksimālo no visiem darbibas.id neskatoties uz to, ka mums interesē tikai tie, kuriem d2.kvits_id = k.id? Vai arī šo lietu garantē group by?

Jā atgriezīs gan vienmēr visiem.

Bet tā kā es neredzēju nekādu ierobežojošo WHERE klauzu uz sākotnējām kvītīm, tad tā var droši darīt, jo tik vai tā mums vajag noskanēt visu darbību tabulu.

Ja uz kvitīm ir WHERE klauza, kas pamatīgi ierobežo pašas atlasītās kvītis, tad tavs variants, kur bija korelētais apkašvaicājums (tb tāds, kas atkarīgs no atlasītās vērtības virsselektā) varētu būt labāks, jo tātad mums ir 2 varianti:

1) atlasīt vienā rāvienā visus maximālos idus darbību tabulā visām kvītīm un tad joinot tikai ar šiem ierakstiem. Tas varētu derēt tad, ja mums interesē pilnīgi visas kvītis vai arī lielākā daļa no tām. Šai gadījumā apakšselektā mēs skanējam darbību tabulu full skanā visu vienreiz.

2) atlasīt tikai tās kvītis, kas mums vajag un tikai tām atlasīt maximālo darbības idu. Šai gadījumā mēs vispirms atlasam vajadzīgo kvīts ierakstu un tad skanējam (vēlmas pēc indexa, protams) darbību tabulu uz ierakstiem tikai konkrētajam kvīts ierakstam. Attiecīgi mums sanāk, ka mēs darbību tabulu skanējam tik reizes, cik ir atlasīto kvīšu, bet toties pēc indexa. Kad atlasīto kvīšu skaits ir relatīvi neliels, tad šis varētu būt izdevīgāks variants.

 

OK būsim godīgi - šis ir tas, kā tas fiziski izpildās Oraclē. Lai būtu 100% pārliecināts par to, ka arī MySQLā ir tāpat, vajadzētu uzraut tabulas MySQLā, un paskatīties izpildes plānus.

 

Un kura kvits_id vērtība tiks izmantota GROUP BY klauzā? d.kvits_id vai d2.kvits_id?

d2.kvits_id, jo, protams, ka skatās to kas katram tuvāks, tb tas kas ir tieši šajā selektā nevis kaut kur augšā. Labais stils droši vien gan būtu bijis arī group by klauzā piemest to d2. Kaut gan patiesībā subselectā varam arī mierīgi rakstīt vispār nekvalificējot darbību tabulu, jo vienmēr ņem to, kas tuvākā, t.i.:

select k.id, k.nosaukums, d.id, d.kvits_id, d.darbiba
FROM kvitis k LEFT JOIN darbibas d ON k.id = d.kvits_id
WHERE d.id IN (
 SELECT max(id) FROM darbibas
 GROUP BY kvits_id)
OR d.id IS NULL
/

Edited by Gints Plivna
Link to comment
Share on other sites

Paldies, Gint.

Sapratu sakni savai nesaprašanai. :)

Biju iedomājies, ka ja nepieliks to ierobežojumu pie select max, tad gala rezultātā vienmēr atgriezīs maksimālo darbiba.id (neatkarīgi no kvits.id), taču tā nav, jo kaut arī tas select max atgriež pilnīgi visus, galā izmantotie vienaalga ir ierobežoti ar JOIN ierobežojumu.

 

P.S. Kaut kā sarežģīti sanāca...

Link to comment
Share on other sites

×
×
  • Create New...