2017-10-10 66 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',我想要20個媒體標記爲'%hol%'(節假日,好萊塢...)

獲得過濾媒體的作品,但我不知道如何獲得20個媒體。

這裏是我的SQL查詢,而無需過濾:

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查詢:

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 ? ...] 

(最後一個參數是我的標籤)

兩個查詢的工作很好,但我找不到限制我的過濾結果的方法。這裏是我的篩選查詢結果的一個樣本:

+----+-------------+-------+-------------------+---------+------------+ 
| 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解決方案?也許使用存儲過程?

謝謝!

編輯:

這是我想用限= 7一樣的結果:

+----+-------------+-------+-------------------+---------+------------+ 
| 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 | 
+----+-------------+-------+-------------------+---------+------------+ 

我有9行,但只有7 distincts媒體ID。每個媒體都有一個標籤,如'%a%'。

編輯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可以爲每個媒體構建一個標記字符串,並且外部聯接此結果。然後根據需要

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條記錄。您可以使用存儲過程來傳遞限制的兩個參數並選取已過濾的結果

+0

不幸的是,我得到了10條記錄,而不是10個媒體。由於一些媒體有很多標籤,因此在結果中返回的次數不止一次。播放此請求會返回10條記錄,但只有4個媒體。不過謝謝! – Rylyn

+0

你可以分享你的預期結果演示嗎? –

+1

當然,我編輯我原來的帖子,以添加預期的結果:) – Rylyn