1
SELECT cf.FK_collection, c.collectionName,
  uf.FK_userMe, uf.FK_userYou,
  u.userId, u.username
FROM userFollows as uf
INNER JOIN collectionFollows as cf ON uf.FK_userMe = cf.FK_user
INNER JOIN collections as c ON cf.FK_collection = c.collectionId
INNER JOIN users as u ON uf.FK_userYou = u.userId
WHERE uf.FK_userMe = 2

やあみんな。

私はこのクエリを作成しようとしていますが、もちろん、私が望んでいるものである複数の行を返すため、もちろん望んでいませんが、そうではありません。説明してみましょう:

サイトでユーザーのアクティビティを表示するために、collectionFollows と userFollows の両方を取得しようとしています。しかし、これを行うと、ユーザーが 1 つしかフォローしていない場合でも、userFollows から複数の行が作成されます。これは、複数の collectionFollows をフォローしているために発生します。

したがって、結果を表示すると、次のように返されます。

John is following 'webdesign'
John is following 'Lisa'
John is following 'programming'
John is following 'Lisa'

複数のクエリを作成する必要があるか、サブクエリを使用する必要があるかを知りたいですか? ベストプラクティスは何ですか?そして、どのようにクエリを書くのでしょうか?

4

1 に答える 1

3

実際には、まったく関係のない 2 つのクエリを組み合わせています。特にあなたもそのように報告しているので、それらを個別のクエリとして保持します。必要に応じて、UNION ALL を使用してこれらのクエリを組み合わせることができます。このようにして、アイテムの種類に関係なく、フォローしているアイテムの名前のリストだけが得られます。必要に応じて、それも指定できます。

SELECT 
  cf.user, 
  cf.FK_collection as followItem, 
  c.collectionName as followName,
  'collection' as followType
FROM collectionFollows as cf
INNER JOIN collections as c ON cf.FK_collection = c.collectionId
WHERE cf.user = 2
UNION ALL
SELECT 
  uf.FK_userMe, 
  u.userId, 
  u.username
  'user' as followType
FROM userFollows as uf
INNER JOIN users as u ON uf.FK_userYou = u.userId
WHERE uf.FK_userMe = 2

別の方法として、PHP で一意の値をフィルター処理することもできますが、それでもクエリは失敗します。内部結合のため、ユーザーが他のユーザーのみをフォローしている場合、またはコレクションのみをフォローしている場合、結果は得られません。結果を得るには、両方の少なくとも 1 つが必要です。INNER JOIN を LEFT JOIN に変更することもできますが、それでもクエリを後処理して double をフィルタリングし、NULL 値を除外する必要があります。

UNION ALL は高速です。それ以上の処理を行わずに、2 つのクエリ結果をくっつけるだけです。これは、(DISTINCT のように) double もフィルター処理する UNION とは異なります。この場合、ユーザーはコレクションまたは他のユーザーを一度しかフォローできないと想定しているため、必要ありません。したがって、これらのクエリは重複したレコードを返すことはありません。その場合、UNION ALL は問題なく動作し、UNION よりも高速になります。

UNION ALL とは別に、2 つの個別のクエリも問題ありません。

于 2012-09-04T06:43:43.693 に答える