2

データベースでユーザーを検索し、それぞれに対して別のテーブルで JOIN を作成したいと考えています。ここに私のテーブルがあります:

USERS: id, firstname, lastname, [...] - ユーザーのデータを含む

FRIENDS: fan_id, idol_id, [...] - どのユーザーがどのユーザーをフォローしているか

ここに私の検索クエリ、クラシックがあります:

SELECT `id`, `username`, `firstname`, `lastname`, `lang`, `twitter`, `facebook`, `picture`, `regdate`
FROM `users`
WHERE `username` LIKE ?
OR `email` LIKE ?
OR `firstname` LIKE ?
OR `lastname` LIKE ?
OR `twitter` LIKE ?
OR `facebook` LIKE ?
ORDER BY `username`;

だから今、私は、検索されたユーザーとこれを求めているユーザーとの関係を含む、友達テーブルを取得したいと考えています。

これが私が考えたことです:

SELECT `id`, `username`, `firstname`, `lastname`, `lang`, `twitter`, `facebook`, `picture`, `regdate`,
GROUP_CONCAT(
    CONCAT_WS(':', `fan_id`, `idol_id`) SEPARATOR ';'
) AS relations
FROM `friends`, `users`
WHERE (`username` LIKE ?
OR `email` LIKE ?
OR `firstname` LIKE ?
OR `lastname` LIKE ?
OR `twitter` LIKE ?
OR `facebook` LIKE ?)
AND (
(`fan_id` = 100 AND `idol_id` = `id`)
OR
(`fan_id` = `id` AND `idol_id` = 100)
)
ORDER BY `username`;

relations実際には、検索されたユーザーが表示され、fan_idかつ検索されたユーザーが表示された場合、idol_idまたはその逆である場合に取得したいと考えています。しかし、最初のクエリでユーザーを検索すると、2 行、2 ユーザー (ids = 80& 125) が表示されます。2番目のクエリでは、1行しかありません(id = 80)が、クエリの半分が機能していることをrelations示しています...100:80;100:125

relations参考までに、( に)ない場合の結果も知りたいので、試してみIFNULL(..., 0)ましたが、それ以上はありません。

ご協力ありがとうございました。

4

2 に答える 2

3

これは、あなたが目指していると思うものの推測に基づいています。

select users.id,users.firstname,
case 
when CONCAT_WS(';',t1.fans,t2.idols)='' then null
else CONCAT_WS(';',t1.fans,t2.idols)
end as relations
from users left join 
(
select CONCAT_WS(':',fan_id,idol_id) as fans,idol_id
from friends
where fan_id=80
) as t1
on users.id=t1.idol_id
left join
(
select CONCAT_WS(':',fan_id,idol_id) as idols,fan_id
from friends
where idol_id=80
) as t2
on users.id=t2.fan_id
where id=100

Sqlfiddleは、ID 80 のユーザーを検索している ID 100 のユーザーの結果です。

where fan_id=80where idol_id=80検索対象のユーザーの正しい ID に設定する必要があり、検索を行っwhere id=100ているユーザーを見つけるための wheres に置き換えることができます。または、3 つすべてを削除して、全員の相互関係のリストを取得することもできます。

- -編集 - -

スクフィドル

このクエリは詳細を提供しませんが、友人を 1 回だけ検索し、ユーザーを 1 回だけ検索します。具体的には、アイドル列とファン列の ID を保持しなくなり、これらの列は 1 または null になります。1 は、ユーザーが他のユーザーのユーザーであることを意味するため、ユーザー 125 はユーザー 100 を検索し、ユーザー 100fan - null | idol - 1のファンではなく、ユーザー 100 のアイドルであることを意味します。ファンとアイドルの両方の場合は 2、一方のみの場合は 1、どちらでもない場合は 0 です。

select users.id,users.firstname,sum(t1.fan) as fan,sum(t1.idol) as idol,
case 
when t1.fan is null and t1.idol is null then null
else count(*) 
end as relations
from users
left join
(
select fan_id,idol_id,
case when fan_id=100 then 1 end as idol,
case when idol_id=100 then 1 end as fan
from friends
where fan_id=100 or idol_id=100
) as t1
on users.id=t1.fan_id or users.id=t1.idol_id
where firstname like '%user1%'
group by id

検索対象のユーザーの ID を変更する必要がある 4 つの場所、すべて 100 です。そして、一番下の where 句には、必要なものを入力できます。

于 2012-09-14T18:41:03.870 に答える
2

使用している古いオメガ結合モデルを使用するよりも、標準JOIN構文を使用する方がはるかに簡単です。

複数テーブルのクエリでは、おそらく列名を修飾する必要があります。

いわゆるリード テーブルで結合を開始します。あなたの場合、ユーザーごとに行が必要なので、それで結合を開始します。

WHERE 内の基準のカスケードが長いORと、クエリのパフォーマンスが非常に低下します。代わりに、ある種の FULLTEXT (バイナリ モード) 検索を検討することをお勧めします。

バッククォートは読みやすさを阻害するため、テーブルまたは列が予約語と同じ名前である場合を除いて必要ありません。

GROUP_CONCATクエリに集計関数がありますが、対応するGROUP BY句がありません。両方が必要です。(必要のない許容可能な言語ショートカットがありGROUP BYますが、デバッグ中はそれらを避ける必要があります。)

あなたの参加基準を理解しようとしていますが、わかりません。id = 100 の何が特別なのかわかりません。しかし、結合の 2 番目の部分で、idol_id = 100ではなくを探すことは可能fan_id = 100ですか?

             (f.fan_id = u.id AND  f.idol_id = 100)

あなたが持っているものは、あなたのプロジェクトのこの部外者には論理的ではないようです。

これを試すことをお勧めします:

SELECT u.id, u.username, 
       u.firstname, u.lastname, 
       u.lang, u.twitter, u.facebook, 
       u.picture, u.regdate,
       GROUP_CONCAT(CONCAT_WS(':', f.fan_id, f.idol_id) SEPARATOR ';') AS relations
  FROM users u
  JOIN friends f ON  (                  
             (f.fan_id = 100 AND f.idol_id = u.id)
                OR
             (f.fan_id = u.id AND  f.idol_id = 100)
            )
 WHERE u.username LIKE ?
    OR u.email LIKE ?
    OR u.firstname LIKE ?
    OR u.lastname LIKE ?
    OR u.twitter LIKE ?
    OR u.facebook LIKE ?
 GROUP BY u.id, u.username, 
       u.firstname, u.lastname, 
       u.lang, u.twitter, u.facebook, 
       u.picture, u.regdate
 ORDER BY u.username
于 2012-09-14T18:25:59.220 に答える