MySQL: DISTINCT 2 rows...
7 naročnikov
7 naročnikov
Č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
1 | 1 | 3 | blablabla | 1043684100
2 | 1 | 2 | blablabla | 1049146320
3 | 2 | 1 | blablabla | 1049146920
4 | 3 | 1 | blablabla | 1049147100
5 | 2 | 3 | blablabla | 1049153340
6 | 1 | 2 | blablabla | 1049627280
Z navadnim DISTINCT ukazom (SELECT DISTINCT fromuser, touser FROM zasebna_sporocila) dobim takšen rezultat:
fromuser | touser
1 | 3
1 | 2
2 | 1
3 | 1
2 | 3
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? :)
19 odgovorov
@blackmamba tudi o tem sem že razmišljal, ampak v tvojem primeru bi moral nekam še vstavit user id spremljivko, ki je vezana na določenega člana.
@Vini:
Poizvedba je potem enostavna:
SELECT
zasebna_sporocila.*
FROM
zasebna_sporocila_pomozna,
zasebna_sporocila
WHERE
zasebna_sporocila_pomozna.user_id = 1 AND
zasebna_sporocila.id = zasebna_sporocila_pomozna.sporocilo_id
ORDER BY
zasebna_sporocila_pomozna.datum;
Tvoja koda potem vrne rezultate v tabeli, ki so vezane na uporabnika z recimo ID št. 1. Ampak s tem še ne dobim groupiranih / unikatnih poizvedb.
Primer:
dva uporabnika, eden z ID 1 in drug z ID 2, se med sabo dopisujete. Potem si dopusujeta še uporabnika z ID 1 in ID 3. In pa recimo up. ID 2 z up. ID 3.
Ker sem recimo jaz up. ID 1, želim dobite en rezultat id 1 & id 2, ter id 1 & id 3. Razmerje med ID 2 in ID 3 me pač ne "zanima", ker so pač zasebna sporočila.
Uf kako bi to bilo lažje obrazložiti v živo :)
Saj zdaj razmišljam, da je najlažje pogledati primer kar na FB strani:
https://www.facebook.com/messages/ (leva stran, kjer se nahajajo vsa sporočila med uporabniki)
Lucifix, imaš prav, seveda, moja napaka. Potrebuješ dve ID polji, v kateri zapišeš oba IDja v dva zapisa, enkrat fromuser v prvi ID, touser v drugi ID, v drugi zapis pa ravno obratno.
Način brez dodatne tabele. Vsi zadnji chati userja id=123, pogrupirani, sortirani po datumu.
V rezultatu "user1" je vedno userid=123, v "user2" je pa userid tistega s katerim je chatal.
Sporoči koliko časa se query izvaja in EXPLAIN.
SET @user_id = 123;
SELECT
IF(from_user = @user_id, from_user, to_user) AS user1,
IF(from_user = @user_id, to_user, from_user) AS user2,
`date`
FROM `zasebna_sporocila`
WHERE from_user=@user_id OR to_user=@user_id
GROUP BY user1, user2
ORDER BY `date` DESC;
Jao kaj so delali s strukturo tabel v sistemu phpBB2?!?! Ko nekdo dobi ZS, se ustvari nova vrstica samo za pošiljatelja - ala sent message. Groza za programiranje...
Hvala še 1x vsem za pomoč, ampak tokrat bom pa vrgel puško v koruzo in začel s čim bolj produktivnim :/
Ravno zadnjič sem nekaj podobnega delal. Torej PM sistem na podoben način kot ima FB. Nisem prebral vseh sporočil, vendar na kratko jaz bi dodal še eno polje thread_id.
Hmm nevem zakaj ne das index na from, to, in id.
In potem samo simple poizvedba
SELECT * FROM sporocila WHERE sporocila.to = 3 OR sporocila.from = 3 ORDER BY sporocila.id DESC
3 = id trenutno prijavlenega uporabnika.