2017-10-10 20 views
1

私はメディア(写真、音楽、ビデオなど)を注文している簡単なアプリケーションを書いています。各メディアは、0〜多くのタグに関連付けられます。 私の目標は、私が自分のメディアを検索することができるUIを持たせることです(例えば、%hol%のようなタグを付けた画像や動画を表示し、休日のタグ付き写真とハリウッドのタグ付き写真を返す)。結合と条件によるSQLクエリ結果の制限

Table medias 
+---------+--------------+------+-----+---------+----------------+ 
| Field | Type   | Null | Key | Default | Extra   | 
+---------+--------------+------+-----+---------+----------------+ 
| id  | int(11)  | NO | PRI | NULL | auto_increment | 
| path | varchar(400) | NO | UNI | NULL |    | 
| type | varchar(5) | NO |  | NULL |    | 
| libelle | varchar(200) | NO |  | NULL |    | 
| ratings | int(2)  | NO |  | NULL |    | 
+---------+--------------+------+-----+---------+----------------+ 

Table tags 
+---------+--------------+------+-----+---------+----------------+ 
| Field | Type   | Null | Key | Default | Extra   | 
+---------+--------------+------+-----+---------+----------------+ 
| id  | int(11)  | NO | PRI | NULL | auto_increment | 
| libelle | varchar(200) | NO | UNI | NULL |    | 
+---------+--------------+------+-----+---------+----------------+ 

Table medias_tags 
+----------+---------+------+-----+---------+-------+ 
| Field | Type | Null | Key | Default | Extra | 
+----------+---------+------+-----+---------+-------+ 
| id_media | int(11) | NO | PRI | NULL |  | 
| id_tag | int(11) | NO | PRI | NULL |  | 
+----------+---------+------+-----+---------+-------+ 

私は多くのマスコミを持っているように、私は結果を制限しなければならなかった:

は、ここに私のデータベースです。私のフロントエンドでは、ページネーションシステムを作って、自分のページに応じて私のメディアを照会しました(たとえば、3ページ目の場合は、SQL文にLIMIT 20 OFFSET 60を入れます)。

私はメディアをフィルタリングしようとしています。私は検索バーを持っていて、「hol」と入力すると、「%hol%」(祝日、ハリウッド...)のようなタグを付けられた20のメディアを取得したいと考えています

フィルタメディアを取得するには、正確に20メディアを取得する方法。

ここに私のSQLクエリは、フィルタリングなしだ:私はどちらの問合せ作業がうまく

SELECT 
medias.id, medias.path, medias.type, medias.libelle as libelle, medias.ratings, tags.libelle as tag 
FROM medias 
left outer join medias_tags on medias.id = medias_tags.id_media 
left outer join tags on tags.id = medias_tags.id_tag 
WHERE tags.libelle LIKE ? [OR tags.libelle LIKE ? ...] 

(最後のパラメータは、私のタグです)

、しかし:

SELECT 
medias.id, medias.path, medias.type, medias.libelle as libelle, medias.ratings, tags.libelle as tag 
FROM (select * from medias LIMIT ? OFFSET ?) medias 
left outer join medias_tags on medias.id = medias_tags.id_media 
left outer join tags on tags.id = medias_tags.id_tag 

そして、ここでは私のフィルタリングSQLクエリですフィルタリングされた結果を制限する方法を見つけることができません。フィルタリングクエリの結果のサンプルは次のとおりです。

+----+-------------+-------+-------------------+---------+------------+ 
| id | path  | type | libelle   | ratings | tag  | 
+----+-------------+-------+-------------------+---------+------------+ 
| 11 | mock/02.jpg | PHOTO | 02.jpg   |  0 | dark  | 
| 1 | mock/03.jpg | PHOTO | Purple   |  5 | wallpapper | 
| 3 | mock/01.jpg | PHOTO | Wave    |  5 | wave  | 
| 3 | mock/01.jpg | PHOTO | Wave    |  5 | wallpapper | 
+----+-------------+-------+-------------------+---------+------------+ 

どのようにしてn個の異なるメディアIDだけを返すようにフィルタリング結果を制限できますか?純粋なSQLソリューションはありますか?たぶん、ストアドプロシージャですか?

ありがとうございます!

編集:私は9行を持っていますが、わずか7 distinctsメディアID

+----+-------------+-------+-------------------+---------+------------+ 
| id | path  | type | libelle   | ratings | tag  | 
+----+-------------+-------+-------------------+---------+------------+ 
| 11 | mock/02.jpg | PHOTO | 02.jpg   |  0 | dark  | 
| 7 | mock/01.jpg | PHOTO | NEWLY ADDED MEDIA |  8 | wallpapper | 
| 2 | mock/02.jpg | PHOTO | Night    |  5 | wallpapper | 
| 2 | mock/02.jpg | PHOTO | Night    |  5 | dark  | 
| 1 | mock/03.jpg | PHOTO | Purple   |  5 | wallpapper | 
| 4 | mock/03.jpg | PHOTO | Purple 2   |  5 | wallpapper | 
| 5 | mock/03.jpg | PHOTO | Purple 3 EDITED |  8 | wallpapper | 
| 3 | mock/01.jpg | PHOTO | Wave    |  5 | wave  | 
| 3 | mock/01.jpg | PHOTO | Wave    |  5 | wallpapper | 
+----+-------------+-------+-------------------+---------+------------+ 

は、ここで私は限界= 7で欲しい結果です。すべてのメディアに '%a%'のようなタグがあります。

EDIT 2:誰かが回答を投稿しましたが、削除しました。彼のアイデアは、タグを連結することでした。

そのような何か:

+----+-------------+-------+-------------------+---------+------------+ 
| id | path  | type | libelle   | ratings | tag  | 
+----+-------------+-------+-------------------+---------+------------+ 
| 11 | mock/02.jpg | PHOTO | 02.jpg   |  0 | dark  | 
| 7 | mock/01.jpg | PHOTO | NEWLY ADDED MEDIA |  8 | wallpapper | 
| 2 | mock/02.jpg | PHOTO | Night    |  5 | wallpapper, dark | 
| 1 | mock/03.jpg | PHOTO | Purple   |  5 | wallpapper | 
| 4 | mock/03.jpg | PHOTO | Purple 2   |  5 | wallpapper | 
| 5 | mock/03.jpg | PHOTO | Purple 3 EDITED |  8 | wallpapper | 
| 3 | mock/01.jpg | PHOTO | Wave    |  5 | wave, wallpapper  | 
+----+-------------+-------+-------------------+---------+------------+ 

しかし、私は、このSQLクエリを作成する方法が分からない...

+0

として適用[このポスト](https://stackoverflow.com/questions/13525656/limit-a-left-join-on-the-first-table)が役立つかもしれません。 – mseifert

+0

ありがとうmseifert。私はこの投稿を見ているが、それは私の問題を解決するようではない。結果を制限するために使用されるサブクエリは、すべてのメディアを取得するために最初のクエリで使用するものですが、結果をフィルタリングするためには機能しません。テーブルAを制限しようとしていますが、結合されたテーブルBに条件があります。 – Rylyn

+1

アイデア連結されたタグを使用すると偉大なので、クエリを書くのがはるかに簡単になります。 –

答えて

1

GROUP_CONCATを使用してメディアごとにタグ文字列を作成し、この結果を外部結合します。次に、あなたのLIMIT句は希望

select 
    medias.id, 
    medias.path, 
    medias.type, 
    medias.libelle, 
    medias.ratings, 
    mtags.tags 
from medias 
left outer join 
(
    select id_media, group_concat(tags.libelle order by tags.libelle) as tags 
    from medias_tags 
    join tags on tags.id = medias_tags.id_tag 
    group by id_media 
) mtags on mtags.id_media = medias.id 
order by medias.id 
limit 20 offset 60; 
+0

これは完璧に動作しているようで、とても読みやすいです! – Rylyn

0

あなたはこのように期待していますか?

SELECT 
medias.id, medias.path, medias.type, medias.libelle as libelle, medias.ratings, tags.libelle as tag 
FROM medias 
left outer join medias_tags on medias.id = medias_tags.id_media 
left outer join tags on tags.id = medias_tags.id_tag 
WHERE tags.libelle LIKE ? [OR tags.libelle LIKE ? ...] 
order by medias.id 
limit 0,10 

ここでは、最初の10レコードに制限があります。 2つの制限のパラメータを渡してフィルタリングされた結果を選択するためにストアドプロシージャを使用できます。

+0

残念ながら、私は10のメディアを取得するのではなく、10のレコードを取得します。いくつかのメディアは多くのタグを持っているため、結果に複数回返されます。このリクエストを再生すると、10個のレコードが返されますが、メディアは4個だけになります。とにかくありがとう ! – Rylyn

+0

期待どおりの結果をデモで共有できますか? –

+1

確かに、元の投稿を編集して期待した結果を追加しました:) – Rylyn

関連する問題