簡體   English   中英

如何在MySQL子查詢中使用GROUP BY

[英]How to use GROUP BY in MySQL subquery

我正在使用phpMyAdmin提交查詢。 在子查詢中使用GROUP BY時,整個應用程序將掛起且沒有錯誤,直到重新啟動瀏覽器為止。

我有三個表: files存儲有關上載文件的信息, file_category定義文件的可用類別, file_category_r存儲文件與類別之間的關系。

我想計算每個類別有多少個文件,但是某些文件在文件表中可以有多個條目,因此我需要按files.filename對其進行files.filename

我嘗試了兩種不同的方法,都導致掛起:

SELECT 
    fc.*, 
    (SELECT COUNT(*) FROM file_category_r
        WHERE file_category_r.category_id = fc.id 
        AND file_category_r.file_id IN 
            (SELECT f2.id FROM 
                (SELECT * FROM files f3 GROUP BY f3.filename) f2 
                    WHERE f2.mandant_id = 1) 
    ) as file_count 
FROM file_category fc ORDER BY name ASC

要么

SELECT 
    fc.*, 
    (SELECT COUNT(*) FROM file_category_r
        WHERE file_category_r.category_id = fc.id 
        AND file_category_r.file_id IN 
            (SELECT id FROM files WHERE mandant_id = 1 GROUP BY filename) 
    ) as file_count 
FROM file_category fc ORDER BY name ASC

我沒有看到查詢問題,僅運行子查詢就可以了。 即使刪除GROUP BY也會返回結果,但結果是錯誤的,因為它正在計算重復值。

這是表模式:

CREATE TABLE IF NOT EXISTS `files` (
  `id` bigint(20) unsigned NOT NULL,
  `project_id` bigint(20) unsigned DEFAULT NULL,
  `customer_id` bigint(20) unsigned DEFAULT NULL,
  `opportunity_id` int(11) DEFAULT NULL,
  `task_id` bigint(20) unsigned DEFAULT NULL,
  `calendar_event_id` bigint(20) unsigned DEFAULT NULL,
  `mandant_id` tinyint(4) DEFAULT NULL,
  `time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  `size` float NOT NULL,
  `mime_type` varchar(100) NOT NULL,
  `filename` text NOT NULL,
  `file` longblob NOT NULL,
  `folder_id` int(11) DEFAULT NULL,
  `user_id` int(11) DEFAULT NULL,
  `is_public` tinyint(1) unsigned NOT NULL DEFAULT '0',
  `description` text,
  `file_link` varchar(500) DEFAULT NULL
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=104832 ;

CREATE TABLE IF NOT EXISTS `file_category` (
  `id` int(11) NOT NULL,
  `name` varchar(200) NOT NULL,
  `parent` int(11) DEFAULT NULL
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=445 ;

CREATE TABLE IF NOT EXISTS `file_category_r` (
  `id` bigint(20) unsigned NOT NULL,
  `file_id` bigint(20) unsigned NOT NULL,
  `category_id` int(11) NOT NULL
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=300346 ;

我究竟做錯了什么? 桌子很大,請求是否可能太重? 我沒有主意,請幫忙! 謝謝!

select fc.name, count(*)
from file_category fc
inner join file_category_r fcr on fc.id = fcr.category_id
group by fc.name

但是,對於“某些文件在文件表中可以有多個條目,因此我不太確定,因此我需要按files.filename對其進行分組”。 也許你需要像

select fc.name, count(distinct f.filename)
from file_category fc
inner join file_category_r fcr on fc.id = fcr.category_id
inner join files f on fcr.file_id = f.id
group by fc.name

通常,使用in會導致查詢計划效率低下。 您可以嘗試改用exists

SELECT fc.*, 
        (SELECT COUNT(*)
         FROM file_category_r fcr
         WHERE fcr.category_id = fc.id AND
               exists (select 1 from files f where f.mandant_id = 1 and fcr.file_id = f.id)
        ) as file_count 
FROM file_category fc
ORDER BY name ASC;

現在,您應該添加索引。 file_category_r(category_id, file_id)files(id, mandant_id)

我使用heidisql,而不是phpmyadmin,您的查詢在這里工作正常。 也許phpmyadmin在解析您的查詢時遇到問題。

編輯:而且,查詢長度是有限制的。 如果您的“輸入”語句太長,mysql將返回phpmyadmin應該返回的錯誤。

但是,如果phpmyadmin掛起,我會嘗試執行您的查詢,例如我的mysqlc或其他MySQL客戶端(如heidisql)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM