2012-05-08 18 views
3

を削除私は2つのテーブルを持っています開始ユーザとtarget_userが「user_connected = 0」に設定されている「部屋」はを選択し、単一のクエリ

ここには2つの問題があります。

  1. これらのユーザーをターゲットに設定するにはどうすればよいですか? 明らかにこのクエリは動作しません:可能な場合、私は2番目のクエリを使用しますが、それはこのクエリがトリガされることを意味している場合

    SELECT room_id 
    FROM rooms,users 
    WHERE 
    ( 
    (room_target_user_id=user_id) AND (user_connected=0) 
    )     
    AND 
    (    
    (room_initiating_user_id=user_id) AND (user_connected=0) 
    ) 
    
  2. 私は(これらの部屋を削除するには、同じクエリで、何の問題が好きなんだろうたくさんある各結果のために。それは一度にこれらの部屋を削除することはできませんか?

答えて

3
delete from rooms 
where room_initiating_user_id in (select user_id from users where user_connected = 0) 
    and room_target_user_id in (select user_id from users where user_connected = 0) 
+0

あなたの答えはLajos Arpadありがとうございます。これは確かに非常にエレガントなクエリのようです。 – Baylock

+0

私は助けてくれてうれしかった。また、あなたのuser_idがusersテーブル内で一意であることが確かであれば、私はさらに簡単な解決策があります。 –

+0

私は自分の答えを編集して、user_idがusersテーブル内で一意である場合の代替案を提供しました。 –

0

ユーザーをターゲットにするには、開始ユーザー、および別の1のために1回、2回JOINテーブルusersに必要ターゲットユーザーの場合:

SELECT room.room_id 
FROM rooms room 
INNER JOIN users initiating 
ON room.room_initiating_user_id = initiating.user_id 
INNER JOIN users target 
ON room.room_target_user_id = target.user_id 
WHERE initiating.user_connected=0 AND target.user_connected=0 

これらの部屋を削除するには、サブクエリとして上記を使用することができます。

DELETE FROM rooms 
WHERE room_id IN (
    SELECT room.room_id 
    FROM rooms room 
    INNER JOIN users initiating 
    ON room.room_initiating_user_id = initiating.user_id 
    INNER JOIN users target 
    ON room.room_target_user_id = target.user_id 
    WHERE initiating.user_connected=0 AND target.user_connected=0 
) 
+0

クエリが正しいように見えます、複雑すぎてO(n^4)の複雑さがありますが、これはO(n^2)だけの複雑さで解決できますが、私の答えを見てください。 –

+0

テーブルから削除したり、サブクエリ内の同じテーブルから選択することはできません。 –

+0

@Ezequiel Muns:はい、テーブルエイリアスを使用できます。 bfavarettoはroomsテーブルのエイリアスルームを使用しました。これらのテーブルを作成し、行を埋めてbfavarettoのクエリを実行することで、いつでもテストすることができます。それは動作しますが、それは私の意見では遅すぎるでしょう。 –

1

まず、これらの部屋を選択するために、あなたは二回usersテーブルに参加する必要がありますが:

SELECT r.room_id 
FROM rooms r 
    JOIN users tgt ON r.room_target_user_id = tgt.user_id 
    JOIN users ini ON r.room_initiating_user_id = ini.user_id 
WHERE tgt.user_connected = 0 AND ini.user_connected = 0 

:表ユーザーのための2つの別個のエイリアスを使用する二つの結合分化するようになっています。また、私はJOIN構文を使用して」、古いカンマが部屋を削除するには

を落胆されている参加するのではなく、削除マルチテーブルが必要になります:

DELETE r 
FROM rooms r 
    JOIN users tgt ON r.room_target_user_id = tgt.user_id 
    JOIN users ini ON r.room_initiating_user_id = ini.user_id 
WHERE tgt.user_connected = 0 AND ini.user_connected = 0 
+0

このクエリの複雑さはO(n^4)ですが、問題はO(n^2)の複雑さで解決できるため、これは遅くなります。また、DELETE rではなく、from節にrが指定されているため、deleteだけを書き込むことができます。私は、DELETE rの構文が働いているかどうか分からない。あなたのコードをテストしましたか? –

+0

Ezequiel Munsさん、ありがとうございました。あなたが気にしないなら、私はLajos Arpadによって与えられた最も単純な質問に行くでしょう。 – Baylock

+0

@LajosArpad確かにそうです。 DELETE rは、ユーザーの結合行には触れずに、部屋の行のみを削除するようにクエリに指示します。 FYI:http://dev.mysql.com/doc/refman/5。1/ja/delete.html –

関連する問題