当条件存在时,如何按信息显示所有组?

时间:2012-11-09 17:00:20

标签: php mysql sql group-by

我有一个页面显示上传到我系统上的文件的“文件标签”。每个文件都可以包含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))

4 个答案:

答案 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;