如何使用 group_concat 和左连接计算 mysql 查询的结果

Posted

技术标签:

【中文标题】如何使用 group_concat 和左连接计算 mysql 查询的结果【英文标题】:how to do a count of results of a mysql query with group_concat and left joins 【发布时间】:2021-03-22 16:32:28 【问题描述】:

我正在处理一个带有分页的网页,我现在面临的一个问题是它不适用于我创建的过滤器。

主要分页通过选择具有特定用户 ID 的所有内容来计算我的表格。这在没有过滤器的情况下效果很好,但是使用过滤器我需要更改此查询以添加内部连接和组 concat,因为其他表中的内容被过滤并通过 ID 连接到主表。

我现在有这个过滤器查询:

SELECT DISTINCT games.gameID,games.idUsers,games.gamename,games.comments,games.dateofpurchase,games.lentoutto,games.gameinfo,games.price,games.pictureurl,games.finished,games.rating,games.releasedate, GROUP_CONCAT(DISTINCT labels.labelname ORDER BY labels.labelname) AS labelname, GROUP_CONCAT(DISTINCT category.categoryname ORDER BY category.categoryname) AS categoryname, GROUP_CONCAT(DISTINCT gamemode.gamemode ORDER BY gamemode.gamemode) AS gamemode, GROUP_CONCAT(DISTINCT platform.platform ORDER BY platform.platform) AS platform FROM games LEFT JOIN gamelabels ON gamelabels.gameID=games.gameID LEFT JOIN labels ON labels.labelID=gamelabels.labelID LEFT JOIN categoryconnect ON categoryconnect.gameID=games.gameID LEFT JOIN category ON category.categoryID=categoryconnect.gamescategory LEFT JOIN gamemodesconnect ON gamemodesconnect.gameID=games.gameID LEFT JOIN gamemode ON gamemode.gamemodeID=gamemodesconnect.gamemodeID LEFT JOIN platformconnect ON platformconnect.gameID=games.gameID LEFT JOIN platform ON platform.platformID=platformconnect.platformconnectID WHERE idUsers = '".$userId."' $filter GROUP BY games.gameID ORDER BY gamename

这个过滤器查询就像一个魅力,但你如何计算它返回的数量或行数?

到目前为止,我尝试的所有方法都在选择部分给了我错误。像这样的事情:

SELECT COUNT ( DISTINCT games.gameID,games.idUsers,games.gamename,games.comments,games.dateofpurchase,games.lentoutto,games.gameinfo,games.price,games.pictureurl,games.finished,games.rating,games.releasedate, GROUP_CONCAT(DISTINCT labels.labelname ORDER BY labels.labelname) AS labelname, GROUP_CONCAT(DISTINCT category.categoryname ORDER BY category.categoryname) AS categoryname, GROUP_CONCAT(DISTINCT gamemode.gamemode ORDER BY gamemode.gamemode) AS gamemode, GROUP_CONCAT(DISTINCT platform.platform ORDER BY platform.platform) AS platform) FROM games LEFT JOIN gamelabels ON gamelabels.gameID=games.gameID LEFT JOIN labels ON labels.labelID=gamelabels.labelID LEFT JOIN categoryconnect ON categoryconnect.gameID=games.gameID LEFT JOIN category ON category.categoryID=categoryconnect.gamescategory LEFT JOIN gamemodesconnect ON gamemodesconnect.gameID=games.gameID LEFT JOIN gamemode ON gamemode.gamemodeID=gamemodesconnect.gamemodeID LEFT JOIN platformconnect ON platformconnect.gameID=games.gameID LEFT JOIN platform ON platform.platformID=platformconnect.platformconnectID WHERE idUsers = '".$userId."' $filter GROUP BY games.gameID ORDER BY gamename

【问题讨论】:

【参考方案1】:

我认为您尝试做的是正确的方法,使用子查询。在 mysql 中,每个子查询表都需要一个标识符,该标识符在包装查询的右括号之后传递,如下所示:

SELECT COUNT(*) FROM (
    SELECT DISTINCT games.gameID,games.idUsers,games.gamename,games.comments,games.dateofpurchase,games.lentoutto,games.gameinfo,games.price,games.pictureurl,games.finished,games.rating,games.releasedate, GROUP_CONCAT(DISTINCT labels.labelname ORDER BY labels.labelname) AS labelname, GROUP_CONCAT(DISTINCT category.categoryname ORDER BY category.categoryname) AS categoryname, GROUP_CONCAT(DISTINCT gamemode.gamemode ORDER BY gamemode.gamemode) AS gamemode, GROUP_CONCAT(DISTINCT platform.platform ORDER BY platform.platform) AS platform FROM games LEFT JOIN gamelabels ON gamelabels.gameID=games.gameID LEFT JOIN labels ON labels.labelID=gamelabels.labelID LEFT JOIN categoryconnect ON categoryconnect.gameID=games.gameID LEFT JOIN category ON category.categoryID=categoryconnect.gamescategory LEFT JOIN gamemodesconnect ON gamemodesconnect.gameID=games.gameID LEFT JOIN gamemode ON gamemode.gamemodeID=gamemodesconnect.gamemodeID LEFT JOIN platformconnect ON platformconnect.gameID=games.gameID LEFT JOIN platform ON platform.platformID=platformconnect.platformconnectID WHERE idUsers = '".$userId."' $filter GROUP BY games.gameID ORDER BY gamename
) count_test;

【讨论】:

感谢泰瑞尔!这似乎确实有效!但是根据我的理解(这整个项目对我来说是一个很大的 php 和 mysql 学习曲线),你所做的是为计数(count_test)创建一个临时列,并将整个原始查询作为你通常会放置的位置您选择的列? 欢迎。我们所做的是创建一个只有一列的临时表(count(*))。我们创建临时表的方式称为子查询。我们也可以向子查询添加更多列,它的行为非常类似于常规表。我可以推荐的是使用 MySQL 的EXPLAIN 函数。对于每个 SELECT 查询,您可以预先添加 EXPLAIN,MySQL 的分析器将返回有关它如何处理查询及其结构的有用信息。如果有子查询,它也会报告子查询。 感谢您的解释?

以上是关于如何使用 group_concat 和左连接计算 mysql 查询的结果的主要内容,如果未能解决你的问题,请参考以下文章

当我在查询中使用“GROUP_CONCAT”和“HAVING”时如何计算 MySQL 结果?

使用 SQL 在 Access 中的 5 个表上进行内连接和左连接

具有三个未索引联合表和左连接的 MySQL 查询使数据库负担过重

如何在codeigniter中计算group_concat

oracle中的右连接和左连接有啥区别?如果我们可以实现左连接在右连接中可以做的事情,为啥要使用 2 个单独的连接?

使用 Switch 语句和左连接 Access SQL 选择 Top 1