Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Pobranie z bazy ostatniej wiadomości od lub do użytkownika
mkudej
post
Post #1





Grupa: Zarejestrowani
Postów: 6
Pomógł: 0
Dołączył: 14.08.2012

Ostrzeżenie: (0%)
-----


Witam.
Używam CakePHP i staram się napisać czat w stylu facebook`owego.
Wyjaśnie o co dokładnie mi chodzi:

Posiadam tabele messages z kolumnami
- id
- message
- user_from
- user_to
-date

Oraz tabela uzytkowników (users) z kolumnami
-id
-username
-name
-surname
-password
-email
- itd (IMG:style_emoticons/default/smile.gif)

No i teraz powiedzmy że jestem zalogowany jako użytkownik o id 1 i wchodze do skrzynki wiadomości.
Chciałbym tu widzieć tylko po 1 NAJNOWSZEJ wiadomości w której jestem nadawcą bądź odbiorcą.
Czyli tak jak jest np w skrzynce gmaila, że widizmy ostatnią wiadomość z jakimś użytkownikiem i możemy w nią wejść żeby zobaczyć więcej...
Sprawia mi to nie lada problem, udało mi się dojść do wybrania wiadomości i zgrupowania ich po user_from i user_to, ale problem w tym ze wybiera on wiadomosci z najmniejszym id... czyli pierwsze napisane... A chciałbym żeby wybrał mi najnowsze

Oto zapytanie które prawie rozwiązało mój problem:
  1. SELECT `Message`.`id`, `Message`.`user_from`, `Message`.`user_to`, `Message`.`message`, `Message`.`date`, `UserFrom`.`id`, `UserFrom`.`username`, `UserFrom`.`email`, `UserFrom`.`password`, `UserFrom`.`name`, `UserFrom`.`surname`, `UserFrom`.`city`, `UserFrom`.`street`, `UserFrom`.`born_date`, `UserFrom`.`role`, `UserTo`.`id`, `UserTo`.`username`, `UserTo`.`email`, `UserTo`.`password`, `UserTo`.`name`, `UserTo`.`surname`, `UserTo`.`city`, `UserTo`.`street`, `UserTo`.`born_date`, `UserTo`.`role`
  2. FROM `gametrade_cake`.`messages` AS `Message`
  3. LEFT JOIN `gametrade_cake`.`users` AS `UserFrom` ON (`Message`.`user_from` = `UserFrom`.`id`)
  4. LEFT JOIN `gametrade_cake`.`users` AS `UserTo` ON (`Message`.`user_to` = `UserTo`.`id`)
  5. WHERE ((`user_to` = 1) OR (`user_from` = 1))
  6. GROUP BY UserTo.id, UserFrom.id
  7. ORDER BY `Message`.`date` DESC, `Message`.`id` DESC


Niestety tak jak wspomniałem nie sortuje mi po id DESC tylko robi ASC... Order wogole nie ma na to wpływu..
Drugim problemem jest to że w sumie wybiera 2 ostatnie wiadomości od nadawcy i odbiorcy (dlatego ze wybiera po user_from i user_to), dużo fajniej było by gdyby wybierało tylko 1 ostatnią z najwiekszym id bądź datą...
Wyeliminuje to późniejszy problem przy stronicowaniu.

Zrzuty struktury z mojej bazy, gdyby ktoś miał ochotę sie pobawić.
  1. CREATE TABLE IF NOT EXISTS `messages` (
  2. `id` int(11) NOT NULL AUTO_INCREMENT,
  3. `user_from` int(11) NOT NULL,
  4. `user_to` int(11) NOT NULL,
  5. `message` text NOT NULL,
  6. `date` datetime NOT NULL,
  7. PRIMARY KEY (`id`)
  8. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=15 ;

  1. CREATE TABLE IF NOT EXISTS `users` (
  2. `id` int(11) NOT NULL AUTO_INCREMENT,
  3. `username` varchar(64) NOT NULL,
  4. `email` varchar(128) NOT NULL,
  5. `password` varchar(64) NOT NULL,
  6. `name` varchar(32) NOT NULL,
  7. `surname` varchar(32) NOT NULL,
  8. `city` varchar(64) NOT NULL,
  9. `street` varchar(64) NOT NULL,
  10. `born_date` date NOT NULL,
  11. `role` varchar(32) NOT NULL,
  12. PRIMARY KEY (`id`)
  13. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=6 ;
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 7)
erix
post
Post #2





Grupa: Moderatorzy
Postów: 15 467
Pomógł: 1451
Dołączył: 25.04.2005
Skąd: Szczebrzeszyn/Rzeszów




Pokaż, jakich kryteriów używasz (w kodzie).
Go to the top of the page
+Quote Post
mkudej
post
Post #3





Grupa: Zarejestrowani
Postów: 6
Pomógł: 0
Dołączył: 14.08.2012

Ostrzeżenie: (0%)
-----


Nie bardzo rozumiem co masz na myśli, kod z cake? modelu?
Go to the top of the page
+Quote Post
mmmmmmm
post
Post #4





Grupa: Zarejestrowani
Postów: 1 421
Pomógł: 310
Dołączył: 18.04.2012

Ostrzeżenie: (0%)
-----


  1. SELECT `m`.`id`, `m`.`user_from`, `m`.`user_to`, `m`.`message`, `m`.`date`, `uf`.`id`, `uf`.`username`, `uf`.`email`, `uf`.`password`, `uf`.`name`, `uf`.`surname`, `uf`.`city`, `uf`.`street`, `uf`.`born_date`, `uf`.`role`, `ut`.`id`, `ut`.`username`, `ut`.`email`, `ut`.`password`, `ut`.`name`, `ut`.`surname`, `ut`.`city`, `ut`.`street`, `ut`.`born_date`, `ut`.`role`
  2. FROM
  3. `gametrade_cake`.`messages` AS `m`
  4. JOIN `gametrade_cake`.`users` AS `uf`
  5. ON `m`.`user_from` = `uf`.`id`
  6. JOIN `gametrade_cake`.`users` AS `ut`
  7. ON `m`.`user_to` = `ut`.`id`
  8. WHERE 1 IN (`m`.`user_to`, `m`.`user_to`)
  9. ORDER BY `m`.`date` DESC
  10. LIMIT 1
Go to the top of the page
+Quote Post
mkudej
post
Post #5





Grupa: Zarejestrowani
Postów: 6
Pomógł: 0
Dołączył: 14.08.2012

Ostrzeżenie: (0%)
-----


Cytat(mmmmmmm @ 16.08.2012, 14:46:58 ) *
  1. SELECT `m`.`id`, `m`.`user_from`, `m`.`user_to`, `m`.`message`, `m`.`date`, `uf`.`id`, `uf`.`username`, `uf`.`email`, `uf`.`password`, `uf`.`name`, `uf`.`surname`, `uf`.`city`, `uf`.`street`, `uf`.`born_date`, `uf`.`role`, `ut`.`id`, `ut`.`username`, `ut`.`email`, `ut`.`password`, `ut`.`name`, `ut`.`surname`, `ut`.`city`, `ut`.`street`, `ut`.`born_date`, `ut`.`role`
  2. FROM
  3. `gametrade_cake`.`messages` AS `m`
  4. JOIN `gametrade_cake`.`users` AS `uf`
  5. ON `m`.`user_from` = `uf`.`id`
  6. JOIN `gametrade_cake`.`users` AS `ut`
  7. ON `m`.`user_to` = `ut`.`id`
  8. WHERE 1 IN (`m`.`user_to`, `m`.`user_to`)
  9. ORDER BY `m`.`date` DESC
  10. LIMIT 1


Niestety to zwraca tylko jeden wynik... A chce wybrać po 1 ostatniej wiadomości + pobrać dane użytkowników.
Nie wiem czy będzie to w ogóle możliwe...
Go to the top of the page
+Quote Post
erix
post
Post #6





Grupa: Moderatorzy
Postów: 15 467
Pomógł: 1451
Dołączył: 25.04.2005
Skąd: Szczebrzeszyn/Rzeszów




Kryteria, które wykorzystujesz w metodzie find*.
Go to the top of the page
+Quote Post
mkudej
post
Post #7





Grupa: Zarejestrowani
Postów: 6
Pomógł: 0
Dołączył: 14.08.2012

Ostrzeżenie: (0%)
-----


  1. public function getChats($user_id) {
  2. $this->order = 'Message.date DESC, Message.id DESC';
  3. $data = $this->find('all', array(
  4. 'conditions' => array(
  5. 'OR' => array(
  6. array('user_to' => $user_id),
  7. array('user_from' => $user_id)
  8. ),
  9. )
  10. ));
  11. return $data;
  12. }
Go to the top of the page
+Quote Post
sazian
post
Post #8





Grupa: Zarejestrowani
Postów: 1 045
Pomógł: 141
Dołączył: 19.09.2006
Skąd: B-tów

Ostrzeżenie: (0%)
-----


tak na szybko przyszło mi do głowy coś takiego

  1. WHERE ((`user_to` = 1) OR (`user_from` = 1)) AND `Message`.`id`=(SELECT max(id) FROM messages m WHERE m.user_to=`Message`.user_to AND m.user_from`=`Message`.user_from`)


i ja bym zamienił LEFT JOIN na JOIN - przecież użytkownik zawsze istnieje skoro napisał wiadomość, a patrząc w drugą stronę skoro system zezwolił na wysłanie wiadomości to użytkownik docelowy też istnieje
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 25.08.2025 - 15:44