【问题标题】:How to display all group by information when condition exists?条件存在时如何按信息显示所有分组?
【发布时间】:2012-11-09 17:00:20
【问题描述】:

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

这里的问题是我仍然希望它为File#3 列出TAG1, TAG2。但当然,WHERE 条件正在摆脱TAG2。 我想知道是否有只涉及更改 SELECT 条件的解决方案。我试图创建一个看起来像这样的解决方案:

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

【问题讨论】:

  • 请不要使用SELECT *。此外,您知道,如果您指定的列不是 GROUPed,或者在聚合中,列的实际值是未定义的?

标签: php mysql sql group-by


【解决方案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  

【讨论】:

    【解决方案2】:

    你可以这样做。这是假设“文件”表中有一个名为“文件”的字段。

    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;

    【讨论】:

    • 感谢您的回答。你能想到任何解决方案,只涉及更改查询的 SELECT 部分而不是 WHERE 部分吗?
    • Tom - 您可能能够将当前外部查询作为SELECT 列表的实际子查询。不幸的是,我不太了解 mySQL 的这一部分....
    【解决方案3】:

    这将允许您将 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'
    

    【讨论】:

      【解决方案4】:

      抱歉所有的答案,但仔细想想,你可能最喜欢这个。这样,任何带有适当标签的组都会出现。所以不需要子查询。

       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;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-25
        • 1970-01-01
        • 1970-01-01
        • 2019-03-06
        • 1970-01-01
        相关资源
        最近更新 更多