2012-11-09 33 views
1

我有一個頁面顯示上傳到我的系統上的文件的「文件標籤」。每個文件可以有0個,1個或多個與之關聯的文件標籤。如何在條件存在時按信息顯示所有組?

我已經成功地做了一個頁面,會顯示文件名和他們的標籤,如:

File  Tag(s) 
File#1 None 
File#2 TAG1 
File#3 TAG1, TAG2 

這個SQL查詢將有助於產生上面的數據:

SELECT *, GROUP_CONCAT(`ftg_name` ORDER BY `ftg_name` SEPARATOR ', ') 
    AS `x_file_tag_names` 
FROM `file` LEFT JOIN `link_file_filetag` ON `fileftg_file` = `file_id` 
LEFT JOIN `filetag` ON `ftg_id` = `fileftg_filetag` 
GROUP BY `fileftg_file` ORDER BY `file_created` DESC; 

問題:

我剛在頁面頂部實現了過濾器。允許我在系統中的不同文件標籤之間進行選擇的過濾器。當有人選擇過濾器時,我在WHERE子句中添加一個條件。看看這個查詢:

SELECT *, GROUP_CONCAT(`ftg_name` ORDER BY `ftg_name` SEPARATOR ', ') 
    AS `x_file_tag_names` FROM `file` 
LEFT JOIN `link_file_filetag` ON `fileftg_file` = `file_id` 
LEFT JOIN `filetag` ON `ftg_id` = `fileftg_filetag` 
WHERE `fileftg_filetag` = '1' 
GROUP BY `fileftg_file` ORDER BY `file_created` DESC; 

這將產生我的網頁上這樣的結果:

File  Tag(s) 
File#1 None 
File#2 TAG1 
File#3 TAG1 

這裏的問題是,我仍然希望它列出TAG1, TAG2File#3。但當然WHERE條件正在擺脫TAG2。 我想知道是否有隻涉及改變SELECT條件的解決方案。我試圖創建一個看起來像這樣的解決方案:

SELECT *, IF(ISNULL(`filetag_file`), 'None', 
    (//a subquery that gets all file tags associated with file in outer query)) 
+0

請不要使用'SELECT *'。另外,你知道,如果你指定的列不是'GROUP'ed,或者是一個集合,列的實際值是未定義的? –

回答

0

你可以這樣做。這是假設「文件」表中有一個名爲「文件」的字段。

SELECT *, 
     GROUP_CONCAT(`ftg_name` ORDER BY `ftg_name` SEPARATOR ', ') AS `x_file_tag_names` 

FROM `file` 
     LEFT JOIN `link_file_filetag` ON `fileftg_file` = `file_id` 
     LEFT JOIN `filetag` ON `ftg_id` = `fileftg_filetag` 

WHERE file.file_id in (SELECT file_id 
         FROM `file` 
           LEFT JOIN `link_file_filetag` ON `fileftg_file` = `file_id` 
           LEFT JOIN `filetag` ON `ftg_id` = `fileftg_filetag` 
         WHERE `fileftg_filetag` = '1') 

GROUP BY fileftg_file ORDER BY file_created DESC;

+0

感謝您的回答。你能想到任何解決方案,只涉及改變查詢的SELECT部分​​而不是WHERE部分? – Justin

+0

我剛更新了腳本。我認爲這是錯誤的。 – Tom

+0

Tom - 您可以將當前的外部查詢作爲SELECT'列表的實際子查詢。不幸的是,我不知道mySQL的這一部分,以及.... –

0

這將允許您將group_concat作爲select語句的一部分。我猜測哪些表包含哪些字段,因爲您沒有在聯接中使用表前綴。

SELECT *, 
     (SELECT GROUP_CONCAT(`ftg_name` ORDER BY `ftg_name` SEPARATOR ', ') 
    AS `x_file_tag_names` 
     FROM `file` LEFT JOIN `link_file_filetag` ON `fileftg_file` = `file_id` 
        LEFT JOIN `filetag` ON `ftg_id` = `fileftg_filetag` 
     WHERE file_id = f.file_id 
     GROUP BY `fileftg_file` ORDER BY `file_created` DESC) AS tags 

FROM `file` f 
     LEFT JOIN `link_file_filetag` lff ON lff.`fileftg_file` = f.`file_id` 
     LEFT JOIN `filetag` ON ft.`ftg_id` = lff.`fileftg_filetag` 

WHERE `fileftg_filetag` = '1' 
1

還有一個(SQL Fiddle):

select file, 
     group_concat(ftg_name order by ftg_name separator ', ') as tag_names 
from file 
left join link_file_filetag on fileftg_file = file_id 
left join filetag on ftg_id = fileftg_filetag 
where exists (select * 
       from link_file_filetag 
       where fileftg_filetag = 1 
        and fileftg_file = file_id) 
group by fileftg_file 
order by file_created desc; 

結果:

FILE TAG_NAMES 
File#2 TAG1 
File#3 TAG1, TAG2 
0

對不起,所有的答案,但經過考慮之後,你可能會喜歡這一個最好的。這樣,任何具有相應標籤的組都會出現。所以不需要子查詢。

SELECT *, GROUP_CONCAT(`ftg_name` ORDER BY `ftg_name` SEPARATOR ', ') 
    AS `x_file_tag_names` FROM `file` 
LEFT JOIN `link_file_filetag` ON `fileftg_file` = `file_id` 
LEFT JOIN `filetag` ON `ftg_id` = `fileftg_filetag` 
GROUP BY `fileftg_file` 
HAVING SUM(CASE WHEN `fileftg_filetag` = '1' THEN 1 ELSE 0 END) > 0 
ORDER BY `file_created` DESC;