我有一个页面显示上传到我系统上的文件的“文件标签”。每个文件都可以包含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, TAG2
列出File#3
。但当然WHERE条件正在摆脱TAG2
。
我想知道是否有一个只涉及改变SELECT条件的解决方案。我试图创建一个看起来像这样的解决方案:
SELECT *, IF(ISNULL(`filetag_file`), 'None',
(//a subquery that gets all file tags associated with file in outer query))
答案 0 :(得分: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
答案 1 :(得分: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;
答案 2 :(得分: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'
答案 3 :(得分: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;