2016-09-27 8 views
3

特定のユーザーがejabberdアーカイブテーブルからチャットしたすべてのユーザーで最後のメッセージを注文したいと考えています。私が使用している各グループから最新のレコードを取得

のフィールドは、これらの

  • ID(メッセージID)
  • ユーザ名(ユーザ名コピー)(とチャットしているユーザー)
  • bare_peer
  • TXT(テキストチャットです)
  • のcreated_at(時間が作成した)

私はTRYIよ何実現するには、そのようなものですが、bare_peerでユーザー名を1_usernodeとし、最後のメッセージのみをグループ化する必要があります。 私はすでに多くのクエリをテストしましたが、どれもうまくいきませんでした。 これは私が試した最初のクエリです。

SELECT id, username, bare_peer, txt FROM archive where 
username = '1_usernode' GROUP BY bare_peer ORDER BY created_at DESC; 

これは出力です。

+------+------------+-------------------------------------------------------+---------------------+ 
| id | username | bare_peer    | txt       | created_at   | 
+------+------------+------------------------+------------------------------+---------------------+ 
| 1095 | 1_usernode | [email protected] | Hello !!!     | 2016-07-17 21:15:17 | 
| 1034 | 1_usernode | [email protected] | hey sup ?     | 2016-07-13 22:40:29 | 
| 1107 | 1_usernode | [email protected] | oi       | 2016-07-18 00:09:28 | 
| 1078 | 1_usernode | [email protected] | Hello this is just a Test!!! | 2016-07-15 16:30:50 | 
| 1101 | 1_usernode | [email protected] | hey       | 2016-07-18 00:05:55 | 
| 1084 | 1_usernode | [email protected] | Hey how are you?    | 2016-07-15 19:36:44 | 
| 1085 | 1_usernode | [email protected] | Hey how are you doing ?  | 2016-07-17 19:20:00 | 
+0

created_at列がdatetimeデータ型に設定されていますか? –

+0

サンプル出力のすべての 'bare_peer'は一意なので、あなたのクエリに正しく従っているようです。あなたは 'username'でグループ化するつもりでしたか? – Sablefoste

+0

入力データと期待される出力を見せてくれれば助かります。たぶん、SQLフィドルを作成する – PaulF

答えて

0

このクエリをお試しください: -

SELECT archive.id, archive.max_id, archive.username, archive.bare_peer, archive.txt 
FROM archive join 
(SELECT MAX(id) max_id, username, bare_peer, txt 
FROM archivewhere username = '1_usernode' GROUP BY bare_peer) 
tab on archive.id=tab.max_id 
+1

それは私に最も古いメッセージを返しますが、とにかく感謝します!アーカイブから – RenatoCv

+0

SELECT *は に参加(bare_peer BY MAX(ID)max_id、ユーザ名、bare_peer、txtをアーカイブから ユーザ名= '1_usernode' グループを選択)タブ archive.id = tab.max_idに 'このクエリ@RenatoCv –

+0

を試してみてくださいSELECT * 'と' GROUP BY'は同じクエリで有効なSQLではありません。 – axiac

0

使用このクエリそれはHelfulです。日時

として

SELECT MAX(id), username, bare_peer, txt FROM archive where 
username = '1_usernode' ORDER BY created_at DESC 
+0

暗黙的なグループ化(集約関数が使用されていますが、GROUP BY句が存在しないため)、このクエリは単一の行を返し、 'ORDER BY'節は役に立たない(クエリは期待された結果を返さない)。 – axiac

+0

これを達成するには回避策が必要です – RenatoCv

0

宣言のcreated_atは、クエリ

を実行し archive */

INSERT INTO `archive`(`id`,`username`,`bare_peer`,`txt`,`created_at`) 
VALUES (1034,'1_usernode','[email protected]','hey sup ?','2016-07-13 22:40:29'), 
(1078,'1_usernode','[email protected]','Hello this IS just a Test!!!','2016-07-15 16:30:50'), 
(1084,'1_usernode','[email protected]','Hey how are you?','2016-07-15 19:36:44'), 
(1085,'1_usernode','[email protected]','Hey how are you doing ?','2016-07-17 19:20:00'), 
(1095,'1_usernode','[email protected]','Hello !!!','2016-07-17 21:15:17'), 
(1101,'1_usernode','[email protected]','hey','2016-07-18 00:05:55'), 
(1107,'1_usernode','[email protected]','oi','2016-07-18 00:09:28'); 

テーブルのデータこの

DROP TABLE IF EXISTS `archive`; 

CREATE TABLE `archive` (
    `id` INT(11) NOT NULL AUTO_INCREMENT, 
    `username` VARCHAR(50) DEFAULT NULL, 
    `bare_peer` VARCHAR(50) DEFAULT NULL, 
    `txt` TEXT, 
    `created_at` DATETIME DEFAULT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=INNODB DEFAULT CHARSET=latin1; 

/*を試してみてください

+0

問題の列を変更するだけであれば、それはうまくいくはずですか? – RenatoCv

+0

あなたのデータでarchive2という2番目のテーブルを作成し、より早い日付のデータを追加しました。それは私にいつも最も古いメッセージを返します。 – RenatoCv

+0

それは動作します。フィドルで参照してくださいhttp://sqlfiddle.com/#!9/45e67e/2 –

0

は、この次のコードを試してください: -

select m.* 
from 
messages m 
inner join (
select max(id) as maxid 
from messages 
group By (if(username > bare_peer, username, bare_peer)), 
(if(username > bare_peer, bare_peer, username)) 
) t1 on m.id=t1.maxid ; 

メートルは、メッセージテーブルあなたはすべてのユーザ名とbare_peerの最大(のcreated_at)でエントリーをしたい

0

の別名です。 MySQLでこれを行う方法の1つは「持っている」ことですが、私はそれを気に入っていません。 私が最初にすべてのエントリの最大(のcreated_at)を得るでしょう:

select username, bare_peer, max(created_at) as m_ 
from archive 
group by username, bare_peer; 

そして、その結果にテーブルを結合:

select b.* 
from (
    select username, bare_peer, max(created_at) as m_ 
    from archive 
    group by username, bare_peer 
) a 
inner join archive as b on (
    a.username = b.username 
    and a.bare_peer = b.bare_peer 
    and a.m_ = b.created_at 
) 
0

私は「あなたがドンとき、それはcreated_atと列を示し理由を知りたいですt created_atを選択しますか?そして、あなたはなぜgroup byを使用するのか分かりません。グループに分ける必要はありません。

私の説明は次のようになります。select id, username, bare_peer, txt, created_at from archive where username = '1_usercode' order by created_at desc

+0

私は間違って元のクエリからcreated_atを削除しました。 – RenatoCv

0

私はRahautoの答えで一時的な解決策を作成しました。 サブクエリ内の最新のメッセージから正しいIDを返して、そのIDからメッセージの内容を抽出できるようにしました。

SELECT username, bare_peer, txt, created_at FROM archive WHERE id IN (
    SELECT tab.max_id FROM 
    archive JOIN (SELECT MAX(id) max_id, username, bare_peer, txt FROM 
    archive WHERE username = '1_usernode' GROUP BY bare_peer) 
    tab ON archive.id=tab.max_id 
); 
関連する問題