特定のアイテムを持つすべてのユーザーを検索するためにクエリを実行する必要がある2 つの参照 (user_id
および)を持つ 1 つのテーブルがあります。item_id
トリッキーな部分は、結果の数だけでなく、どのアイテムがあるかに基づいて、結果を並べ替える必要があることです。
ここにテーブルがあります:
+--------------+-----------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-----------------------+------+-----+---------+-------+
| user_id | int(11) | NO | | 0 | |
| item_id | int(11) unsigned | YES | | NULL | |
+--------------+-----------------------+------+-----+---------+-------+
したがって、私のクエリは次のようになります。
SELECT user_id, item_id
FROM user_items
WHERE item_id IN (2, 122, 132)
GROUP BY user_id, item_id
HAVING SUM(item_id = 2);
簡単に見えますか?難しい部分は次のとおりです。
item_id = 2 は必須 item_id = 122 および 132 はオプションです。132 以降もオプションです。
次の基準に基づいて結果を並べ替える必要があります。1) すべてのアイテムが見つかった場合。2) アイテム 2 と 122 のみが見つかった場合。3) アイテム 2 のみが見つかった場合。
フィドリング用の SQL フィドル ファイルは次のとおりです: http://sqlfiddle.com/#!2/6b1c1/6/0
私が考えているのは、次のように設定できる方法があれば、次のように言うことです。
IF (item_id = 2 AND item_id = 122 AND item_id = 132) AS matches_all,
IF (item_id = 2, item_id = 122) AS matches_some,
IF (item_id = 2) AS matches_first
更新されたクエリで編集 これまでのところ私が持っているものは次のとおりです。それは私が必要とするものの約 95% です: http://sqlfiddle.com/#!2/6b1c1/47
SELECT user_id, item_id,
@tmp_1 := IF(SUM(item_id = 2), 1, 0) AS tmp_1,
@tmp_2 := IF(SUM(item_id = 122), 1, 0) AS tmp_2,
@tmp_3 := IF(SUM(item_id = 132), 1, 0) AS tmp_3,
@tmp_4 := IF(SUM(item_id = 126), 1, 0) AS tmp_4,
CAST(@tmp_3 + @tmp_4 AS UNSIGNED) AS total_other
FROM user_items
WHERE item_id IN (2, 122, 132, 126)
GROUP BY user_id
HAVING SUM(item_id = 2)
ORDER BY tmp_1 DESC, tmp_2 DESC, total_other DESC
さらにいくつかの詳細:
1) 入力できる項目は最大 12 個までなので、必要に応じてそれぞれに独自の一時フィールドを割り当てることができます。
2) 上記のクエリは、tmp_1 と tmp_2 に対して完全に機能します。アイテム 2 と 122 を持つユーザーがいる場合、それらがリストの一番上に配置されます。残りの 3 ~ 4 (3 ~ 12) については、一致数を計算する必要があるため、CAST(@tmp_3 + @tmp_4
. それらを計算する方法がわかりません。
3) 項目 3 ~ 12 の合計計算が完了すると、それがORDER BY
句の 3 番目で最後の項目になります。
結果の例
SQL fiddle ファイルで提供されているスキーマに基づいて、item_id を持つすべてのユーザーを検索して返される結果を次に示します。2, 122, 132, 126
+---------+--------------+----------------+-------------+
| USER_ID | PRIMARY_ITEM | SECONDARY_ITEM | OTHER_ITEMS |
+---------+--------------+----------------+-------------+
| 39 | 1 | 1 | 2 |
| 54 | 1 | 1 | 0 |
| 55 | 1 | 0 | 0 |
+---------+--------------+----------------+-------------+