ugrás a tartalomhoz

outer join és rendezés

sandrosdj · 2013. Ápr. 27. (Szo), 15.27
Üdv!

Adott az alábbi sql lekérdezés. A lekérdezés több táblából gyűjt adatot, többek között az üzenetek táblából is.
Hogyan lehet megoldani azt, hogy az üzenetek táblából a legutóbb beszúrt sor adatait kérdezze le?
SELECT conversations.id AS id, conversations.name AS name, messages.message AS message, messages.time AS time FROM conversation_members INNER JOIN conversations ON conversations.id=conversation_members.conversation LEFT OUTER JOIN messages ON messages.conversation=conversations.id WHERE conversation_members.user=$user[id] GROUP BY conversations.id ORDER BY messages.time DESC
Az ORDER BY után megpróbáltam megadni neki, hogy idő szerint csökkenő sorrendbe kérdezze le, de nem hozta a kívánt hatást.
 
1

legutóbb beszúrt?

Poetro · 2013. Ápr. 27. (Szo), 17.57
Mit jelent, hogy a legutóbb beszúrt? Mi jellemzi azt?
2

Van egy time mező, amely az

sandrosdj · 2013. Ápr. 27. (Szo), 18.19
Van egy time mező, amely az időt tárolja másodpercben, és amelyiknek a legnagyobb az értéke az a legutóbbi.
3

GROUP BY és HAVING?

Poetro · 2013. Ápr. 27. (Szo), 18.33
GROUP BY és HAVING?
4

Group by-t már tartalmaz a

sandrosdj · 2013. Ápr. 27. (Szo), 18.46
Group by-t már tartalmaz a lekérés, most kiegészítettem a Having-gel, de az eredmény nem változott.
5

És hol szerepel benne a MAX

Poetro · 2013. Ápr. 27. (Szo), 18.57
És hol szerepel benne a MAX és a dátum?
6

Első próbálkozás: GROUP BY

sandrosdj · 2013. Ápr. 27. (Szo), 19.01
Első próbálkozás: GROUP BY conversations.id HAVING MAX(messages.time)
Második: GROUP BY conversations.id HAVING messages.time = MAX(messages.time)
8

Nem szerepel

Pepita · 2013. Ápr. 27. (Szo), 19.54
Az első SELECT-ben nem szerepel a messages.time. Így GROUP BY-ban biztosan nem használhatod, de gyanítom, hogy HAVING-ben sem. (Én mondjuk sorbarendezni is olyan érték alapján szoktam, ami SELECT-ben is van.) Hibaüzi nincs rá?

Valóban az összes beszélgetés (egyetlen) legutóbbi üzenetét akarod lekérdezni? Nekem könnyebb lenne, ha pontosan megfogalmaznád a feladatot és ismerném a táblák struktúráját. Ettől még nem a konkrét megoldást mondanám meg, de valószínűleg tudnék segíteni elérni.
7

Mi a probléma?

MadBence · 2013. Ápr. 27. (Szo), 19.29
Mi az (szövegesen), amit ezzel a lekérdezéssel le akarsz kérdezni? Csak mert itt maga a lekérdezés értelmetlen, hiszen a message-conversation felteszem n:1 kapcsolat, ezek után te a sorokat a beszélgetések alapján csoportosítva akarod lekérni, tehát nyilván értelmetlen a message oszlop (hiszen több sor is tartozhat hozzá).
9

Van három tábla, név és

sandrosdj · 2013. Ápr. 27. (Szo), 20.02
Van három tábla, név és tartalom szerint:
conversations - a beszélgetések azonosítóját és témáját (nevét) tartalmazza.
Mezők: id - name

conversation_members - a beszélgetések tagjait tartalmazó tábla.
Mezők: id - user - conversation - left - read - time
Ahol a conversation a conversations tábla ID-jét tartalmazza.

messages - az üzeneteket tartalmazó tábla.
Mezők: id - user - conversation - message - time
Ahol a conversation a conversations tábla ID-jét tartalmazza.

Ki szeretném listázni az egyes beszélgetéseket (conversations) úgy, hogy az utolsó üzenet ideje és szövege is legyen lekérdezve, valamint csak azok a beszélgetések jelenjenek meg, amelyekben részt vesz az adott felhasználó, az utolsó üzenet érkezésének idejének sorrendjében. Az user mező értéke mindig a felhasználó azonosítója, amely php-ban az $user[id] változóban van tárolva.

A lekérdezésből szeretném megkapni még a left és read mező értékét is.
10

Csak egyeseket?

Pepita · 2013. Ápr. 27. (Szo), 20.22
Úgy gondolom, az összes conversations-t szeretnéd, egyest legalábbis nem tudom, hogy lehetne listázni.

Mivel a Júzer résztvétele fontos, az első SELECT a conversation_members táblát érinti, ahol WHERE user_id szűr, ennek listája megadja a beszélgetéseket (id). (Persze benne lehet a left, stb. mező is.)

A többit - azt javaslom - először csináld meg belső SELECT-ekkel és WHERE-ekkel, utána könnyebb lesz ezeket JOIN-okra cserélni.

A következő (belső) SELECT lekéri a megfelelő id-vel rendelkező conversations bejegyzéseket.

Ezen belül a harmadik SELECT a messages, ahol már menni fog a MAX.

Ezt a hármast rakd össze SELECT-ekkel, aztán meglátjuk, mit lehet belőle "kiJOINolni".

Szerk.: Ha viszont nem csak a legutóbbi messages kell (a listába), akkor nem biztos, hogy menni fog egy lekérdezéssel.
12

Nekem ez jött össze, ami nem

sandrosdj · 2013. Ápr. 27. (Szo), 22.20
Szerk.: Valóban egyszerűbb, megnéztem egy sokadik példát a több selectes lekérdezésre és a funkciók egy részét sikerült megcsinálnom vele.
11

Kiindulásnak

MadBence · 2013. Ápr. 27. (Szo), 22.11
SELECT c.id      id,
       c.name    name,
       m.message message,
       m.time    time
FROM   conversation_members cm
       INNER JOIN conversations c
               ON c.id = cm.conversation
       LEFT OUTER JOIN messages m
                    ON m.conversation = c.id
WHERE  cm.user = 1
       AND m.id = (SELECT id
                   FROM   messages
                   WHERE  conversation = c.id
                   ORDER  BY time DESC
                   LIMIT  0, 1)
GROUP  BY c.id 
A belső SELECT nem szép, azt célszerű eltüntetni, ha lehet.
13

Köszönöm szépen a

sandrosdj · 2013. Ápr. 27. (Szo), 23.21
Köszönöm szépen a segítséget!
Ennek köszönhetően már kezdem érteni, hogy mit s hogyan kellene.
A select eltüntetésére még visszatérek, miután teljesen elsajátítom a bonyolultabb lekérések működését.

Upd.: Ha nincs üzenet az adott beszélgetésben, akkor nem jelenik meg a listában a beszélgetés neve sem. Ezt lehet orvosolni? (Ezért használtam Outer Join-t)
Ezt nem feltétlenül fontos megcsinálni, hiszen meg tudom oldani, hogy a beszélgetés létrehozásakor egyből meg kelljen adni az üzenetet.
14

További "segítség"

Pepita · 2013. Ápr. 29. (H), 21.47
Lehet kicsit hülyén hangzik: én a bonyolultabb lekérdezéseket úgy szoktam kezdeni, hogy egyetlen értelmes magyar mondatban felírom, hogy milyen eredményt szeretnék.

"Keressük az összes beszélgetést és annak az első hozzászólását, amiknek XY Júzer a tagja, ..."

Ha magyarul megvan (és pontosan), akkor az SQL már gyerekjáték :)... (Aztán a sok SELECT, majd JOIN.)