| MySQL: DISTINCT 2 rows... | ||
|---|---|---|
|
Lucifix
20. nov 2012 12:23:05
Pridružen od: 14. okt 2008 744 objav 438 12 0 |
#1
Če se mi kdaj zaplete pri programiranju, pa je to pri kakšnem bolj zahtevnem MySQL stavku in zato vas prosim za pomoč. Imam tabelo zasebna_sporocila, ki ima takšno strukturo: id | fromuser | touser | message | date Z navadnim DISTINCT ukazom (SELECT DISTINCT fromuser, touser FROM zasebna_sporocila) dobim takšen rezultat: fromuser | touser Problem pa je, ker bi rad dobil unikatne poizvedbe. V zgornjem rezultatu se prikaže 1 2 in 2 1 - kar bi želel, da se prikaže kot en rezultat, saj bi rad dobil zgrupirana sporočila med dvema uporabnikoma. Nekako podobno kot ima to narejeno Facebook v zasebnih sporočilih. Nekam bi moral še dodati poizvedbo WHERE (fromuser = 1 OR touser = 1) - rezultat za uporabnika, ki ima id 1. Seveda moram potem na koncu rezultate urediti po datumu (ORDER BY date DESC). Kakršnakoli pomoč več kot dobrodošla! Zakomplicirano? :) |
|
|
Mešetar
20. nov 2012 12:38:34
Pridružen od: 24. nov 2010 1543 objav 1945 962 114 |
||
|
boskor
20. nov 2012 12:47:08
Pridružen od: 14. sep 2011 18 objav 7 1 0 |
#3
probaj s tem: SELECT * |
|
|
Lucifix
20. nov 2012 12:54:14
Pridružen od: 14. okt 2008 744 objav 438 12 0 |
#4
@boskar tvoj primeru bi prišel prav, če bi že imel id od ostalih članov s katerimi je dotični član izmenjal sporočila. Jaz pa želim dobiti vsa ID sporočila, v katerih je sodeloval en uporabnik (npr. id = 1). Problem pa je, ker ima lahko taisti uporabnik (id = 1) svoj id vpisan v row fromuser ali pa touser. @Mešetar mislim, da mi group by ne bo prišel prav... |
|
|
Vini
20. nov 2012 12:54:22
Pridružen od: 1. sep 2006 6612 objav 5234 611 56 |
#5
Takšne poizvedbe nikoli ne boš mogel zadovoljivo optimizirati in bo po vsej verjetnosti trajala preveč časa in ti s tem ubijala strežnik, ko boš imel teh sporočil več. Jaz bi na tvojem mestu dodal še eno tabelo, ki bi vsebovala ID uporabnika, ID sporočila, mogoče še timestamp sporočila, da bo tudi ORDER BY lahko uporabil indeks. V to tabelo ob dodajanju vsakega sporočila dodaš dva zapisa, v enega zapišeš ID od fromuser, v drugega ID od touser, v oba pa isti ID sporočila in isti timestamp. Tole dodajanje dveh zapisov lahko tudi avtomatiziraš z uporabo triggerjev. Poizvedba je potem enostavna: Če v tabeli zasebnasporocilapomozna nastavis indeks na polji user_id in datum, ga bo ta poizvedba tudi uporabila in bo zato tudi seveda super hitra. :) |
|
|
Vini
20. nov 2012 12:59:31
Pridružen od: 1. sep 2006 6612 objav 5234 611 56 |
#6
Če mogoče ni najbolj jasno zakaj je tu potreben tudi indeks na polju datum, sem o tem nekoč davno pisal na svojem sicer že davno mrtvem blogu, pa da se ne ponavljam, je tukaj kar link: SQL in indeksi (2.del) |
|
|
Mešetar
20. nov 2012 12:59:40
Pridružen od: 24. nov 2010 1543 objav 1945 962 114 |
#7
v tem primeru naredis vedno 2 poizvedbe, ena za FROM users, druga za TO user.... in jih groupiras poo menjenih indexih... ni mi pa jasno, kaj je tvoj namen? ce bi rad to delal s sporocili, bi moral voditi idsporocila (root) in potem vsa pripeta sporocila k temu (parentid) ... ce gre za sporocila tipa pri FBju ... ali forumu (ali gmailu)... ce gre za normalen chat pa je zadosti where fromid = 1 OR fromid=2 OR toid=1 OR toid=2 |
|
|
Lucifix
20. nov 2012 13:15:19
Pridružen od: 14. okt 2008 744 objav 438 12 0 |
#8
@Vini mogoče je tvoja rešitev res najbolj primerna. Bolj me skrbi, da bom moral potem preurejati še ostalo kodo, da bo v primeru izbrisa uporabnika ali pa izbrisa kakšnega sporočila potrebno narediti tudi en nov sql stavek, ki bo urejat tisto pomožno tabelo. @Mešetar
To pa je predlagal Vini v svojem postu - če sem te prav razumel. |
|
|
Vini
20. nov 2012 13:17:23
Pridružen od: 1. sep 2006 6612 objav 5234 611 56 |
#9
Lucifix, tudi brisanje sporočila in hkratno brisanje zapisov v pomožni tabeli lahko urediš s triggerji. |
|
|
Lucifix
20. nov 2012 13:21:02
Pridružen od: 14. okt 2008 744 objav 438 12 0 |
||