2011-06-22 12 views
1

私は、次の表があります。私は実行したクエリの望ましい結果がthread_idusernameで最も最近のスレッドから長い最新のメッセージのtitleを一覧表示し、結果をソートすることであるSQL文でサブクエリが多すぎますか?

users: 
    user_id 
    user_name 

message: 
    message_id 
    thread_id 
    to_id 
    from_id 
    title 
    message_text 
    message_date   
    status 

dateで降順に並べ替えます。私は一度に10〜20件程度の結果をリストアップするつもりです。

私が思いついたのはこれまでのことですが、それを複雑にしていて、クエリを書くのに最適な方法があるようです。誰もが同じthread_idを持つすべてのメッセージのcountを取得する方法を知っていれば

SELECT personal_messages.message_id, 
      personal_messages.thread_id, 
      personal_messages.body, 
      users.username 
    FROM users, personal_messages 
    WHERE message_id IN 
     (SELECT MAX(message_id) from personal_messages GROUP BY thread_id) 
    AND users.id IN 
     (SELECT users.id FROM users WHERE users.id = personal_messages.from_id) 
    ORDER BY personal_messages.message_date DESC 
また

、それは素晴らしいだろう!

ヒントをお聞かせください。誰もが同じなthread_idを持つすべてのメッセージの数を取得する方法を知っている場合にも、素晴らしいだろう:

+0

あなたが「デザインパターン」タグを削除したい場合があります。そうでない場合は、あなたの質問に関連すると思われるデザインパターンを明確にします。 – mikemanne

答えて

2

副選択の一つは、不必要な

SELECT personal_messages.message_id, personal_messages.thread_id, personal_messages.body, users.username 
FROM users INNER JOIN personal_messages ON (users.id = personal_messages.from_id) 
WHERE message_id IN (SELECT MAX(message_id) from personal_messages GROUP BY thread_id) 
ORDER BY personal_messages.message_date DESC  

編集することができます!

SELECT MAX(message_id), COUNT(message_id) FROM personal_messages GROUP BY thread_id 
+0

これは部分的に動作します。一番上の部分はうまくいきますが、2番目の部分は 'COUNT'で「オペランドには1列が含まれています」というエラーがスローされます。 – bigmike7801

0
SELECT tbl.message_id, personal_messages.thread_id 
     , personal_messages.body, users.username 
FROM users u 
JOIN personal_messages tbl on tbl. from_id = u.UsersId 
WHERE tbl.message_id IN (SELECT MAX(message_id) from personal_messages 
GROUP BY thread_id) 
ORDER BY personal_messages.message_date DESC 
0

私はあまりにも多くのサブクエリがクエリであるとは思わないが、それはより最適に書き込むことができます。私は、以下のクエリは同様にうまく動作するはずだと思う:私はあなたのクエリを見つけた

SELECT `PM`.`message_id`, `PM`.`thread_id`, `PM`.`body`, `U`.`username` 
FROM `users` `U` 
INNER JOIN `personal_messages` `PM` ON `PM`.`from_id` = `U`.`user_id` 
ORDER BY `PM`.`message_date` DESC; 

問題は、次のとおりです。

  1. 最初のサブクエリ - SELECT MAX(message_id) from personal_messages GROUP BY thread_id - 常に単一の結果セットを返します、そこらでを使用すると、第2のサブクエリの意味
  2. がありません - SELECT users.id FROM users WHERE users.id = personal_messages.from_id - 私の例では

は、Aホープようにあなたは、代わりに内部結合を使用することができますboveは助けます。

また、実際に取得しようとしている情報についてはわかりません。しかし、上記のクエリは、最新のメッセージの詳細とそのスレッドIDとユーザー名を与える必要があります。あなたが既に持っていることはかなり良いです

SELECT * 
FROM (
    SELECT `PM`.`message_id`, `PM`.`thread_id`, `PM`.`body`, `U`.`username` 
    FROM `users` `U` 
    INNER JOIN `personal_messages` `PM` ON `PM`.`from_id` = `U`.`user_id` 
    ORDER BY `PM`.`message_date` DESC; 
) `TT` 
GROUP BY `TT`.`thread_id`; 
+0

クエリがどのように機能するのかわかりません。各スレッドからメッセージを1つだけ選択する方法はありますか? – bigmike7801

+0

@ bigmike7801:上の私の編集クエリをご覧ください、それはあなたにスレッドごとに最新のメッセージを与えるでしょう – Abhay

+0

Nope申し訳ありませんが、特定のスレッドからの最新のメッセージの望ましい結果を提供していません。このクエリーは、 'SELECT personal_messages.message_id、personal_messages.thread_id、personal_messages.body、users.username FROM users INNER JOIN personal_messages ON(users.id = personal_messages.from_id) WHERE message_id IN(SELECT MAX(message_id)FROM個人的なメッセージGROUP BY thread_id) ORDER BY personal_messages.message_date DESC' – bigmike7801

0

EDITED問合せは、スレッドごとに1つの最新のメッセージを選択します。あなたは1つのクエリでそれをすべて行いたい場合は、あなたが得る同じ副選択の一部としてCOUNT(message_id) GROUP BY thread_idを得ることができMAX(message_id) GROUP BY thread_id

SELECT personal_messages.message_id, 
     personal_messages.thread_id, 
     personal_messages.body, 
     users.username, 
     thread.countmessages 
FROM personal_messages 
JOIN users ON users.id=personal_messages.from_id 
JOIN 
    (SELECT COUNT(message_id) countmessages, 
      MAX(message_id) maxmessage_id 
     FROM personal_messages 
     GROUP BY thread_id) AS thread 
    ON thread.maxmessage_id=personal_messages.message_id 
ORDER BY personal_messages.message_date DESC 
関連する問題