0

MySQL を使用して、ドキュメント「リエゾン」を持っていないすべてのユーザーをリストしたいと思います。これは、文書をまったく持っていないユーザー、または文書を持っているがこれらの文書に「連絡」していないユーザーを意味する可能性があります。

MySQL Query を使用するにはどうすればよいですか? うまくいかない!

これが(単純な)モデルです

Users (id, name)
Documents (id, user_id, name, path)
4

6 に答える 6

2

探している正しいクエリは次のとおりです。

SELECT 
    * 
FROM 
    Users 
WHERE 
    id NOT IN (
        SELECT 
            user_id 
        FROM 
            Documents 
        WHERE 
            name = "liaison"
    )

これにより、探している正確な結果が得られます。特定のユーザーがドキュメントを持っていない場合は、リストに表示されます。多くの文書があり、そのうちの 1 つが「リエゾン」である場合、リストには表示されません。

ドキュメントの名前で「liaison」を検索する場合は、 を に置き換えname = "liaison"ますname LIKE "%liaison%"

基本的には、「リエゾン」という名前のドキュメントが指定されていないなど、すべてのユーザーを選択します。

于 2012-12-17T16:31:42.273 に答える
2

これNOT EXISTSは実行可能なソリューションです。別の方法として、大規模なセットでは、「anti JOIN」操作を使用するとパフォーマンスが向上することがあります。

SELECT u.*
  FROM Users u
  LEFT
  JOIN (SELECT d.user_id
          FROM Documents d
         WHERE d.name = 'liaison'
       ) l
    ON l.user_id = u.id
 WHERE l.user_id IS NULL

としてエイリアス化されたインライン ビューlは、'liaison' という名前のドキュメントを持つ user_id のリストを返します。その結果セットは Users テーブルに外部結合され、一致が見つかった行はすべて除外されます (l.user_id IS NULL のテスト)。

NOT EXISTSこれにより、述語を含むクエリに相当する結果セットが返されます。

もう 1 つの方法は、NOT IN述語を含むクエリを使用することです。サブクエリが NULL を返さないことを保証する必要があるため、一般的なアプローチは、サブクエリによって返される列に IS NOT NULL 述語を含めることです。

SELECT u.*
  FROM Users u
 WHERE u.id NOT IN 
       ( SELECT d.user_id 
           FROM Documents d
          WHERE d.user_id IS NOT NULL
            AND d.name = 'liaison'
       )

私は次のようにNOT EXISTSクエリを書きます:

SELECT u.*
  FROM Users u
 WHERE NOT EXISTS 
       ( SELECT 1
           FROM Documents d
          WHERE d.name = 'liaison'
            AND d.user_id = u.id
       )

私の個人的な好みは、その相関サブクエリの SELECT リストでリテラル 1 を使用することです。クエリが 1 行の存在を探しているだけであることを思い出します。)

繰り返しますが、私は通常、「anti-join」パターンが大規模なセットで最高のパフォーマンスを発揮することを発見しました。(各ステートメントの EXPLAIN 出力を確認し、それぞれのパフォーマンスを測定して、状況に最適なステートメントを判断する必要があります。)

于 2012-12-17T16:41:11.337 に答える
1

だから、私はついにうまくいくように見えるこの解決策を思いついた:

SELECT * FROM users u WHERE id NOT IN (SELECT DISTINCT user_id FROM user_documents WHERE name = 'LIAISON') ORDER BY c.lastname, c.firstname
于 2012-12-17T16:26:38.097 に答える
1
SELECT users.*
FROM users left join Documents
     on users.id = Documents.user_id
        and documents.name='LIAISON'
WHERE documents.user_id is null
于 2012-12-17T16:30:05.173 に答える
1
select * from Users where not exists (select id from Documents where Users.id = Documents.id and Documents.name = 'liaison')
于 2012-12-17T16:17:10.000 に答える
0

試す :

SELECT DISTINCT u.*
FROM users u LEFT JOIN documents d ON d.user_id = u.id
WHERE d.id IS NULL OR d.name NOT LIKE '%liaison%'

「liaison」がドキュメントの正確な名前である場合は、パーセント記号を削除します。

于 2012-12-17T16:13:21.963 に答える