【问题标题】:How to use group by to get multiple result set? grouping on multiple columns如何使用 group by 获取多个结果集?在多列上分组
【发布时间】:2011-05-10 13:13:14
【问题描述】:

我有一个名为 product 的表,其中包含以下数据

pid品牌颜色 1 索尼白 2卡西欧灰 3 xoxo蓝 4三星白 5 mvc 银 6 索尼灰 7 xoxo红 8三星银 9 mvc 白色

我需要获取属于每个品牌和颜色的产品总数。所以我写了 2 个不同的查询。

按品牌从产品组中选择 count(pid) 作为总数; 按颜色从产品组中选择 count(pid) 作为总数;

这很好用。但是由于我的产品表数据很大,我认为如果我可以通过单个查询来实现这一点会更好。有可能吗?

【问题讨论】:

  • 这个问题有点令人困惑。当您说“获取属于每个品牌和颜色的产品总数”时,您是指单独获取计数还是先对品牌进行分组,然后按颜色分组再获取计数?
  • 好的,我会说清楚的。我需要单独计算。 IE。每个品牌的产品总数和每种颜色的产品总数。不是品牌和颜色的组合。

标签: php mysql sql database group-by


【解决方案1】:

您可以简单地拥有这两个查询的UNION

( SELECT 1        AS groupType
       , brand    AS grp
       , count(*) AS total
  FROM products 
  GROUP BY brand
)
UNION ALL
( SELECT 2        AS groupType
       , color    AS grp
       , count(*) AS total
  FROM products 
  GROUP BY color
)
ORDER BY groupType
       , grp

如果您想要每个品牌颜色组合的产品数量,您应该将表格按以下两个字段分组:

SELECT brand
     , color
     , count(*) AS total
FROM products 
GROUP BY brand
       , color

【讨论】:

  • 嗨。感谢您的回答。我在这里有一个疑问。与使用 2 个单独的查询相比,使用 union 有什么优势?它会带来更好的性能吗?实际上我在这个例子中提到的品牌和颜色是产品属性。在我的实际表格中,总共有 6 个属性。那么哪种方法会更好呢?所有 6 个查询或 6 个单独查询的联合查询?
【解决方案2】:

根据您的表实际有多大,首先获取品牌/颜色组合的总数并将它们存储到临时表中,然后查询临时表两次以按每个标准查找最终总数可能会更便宜。

也就是说,是这样的:

-- create a temporary table (omitted)

INSERT INTO temp_table (brand, color, total)
SELECT brand, color, COUNT(*) AS total
FROM products
GROUP BY brand, color

SELECT brand, SUM(total) AS total
FROM temp_table
GROUP BY brand

SELECT color, SUM(total) AS total
FROM temp_table
GROUP BY color

【讨论】:

    【解决方案3】:
    select 
    count(*) over (partition by product), 
    count(*) over (partition by color)
    from table
    

    【讨论】:

    • 我认为 MySQL 没有分区。
    • @PMV:你说得对,它是少数不支持窗口函数的 DBMS 之一
    【解决方案4】:
    select brand as `group`, count(pid) from products group by brand
    union all
    select color as `group`, count(pid) from products group by color
    

    【讨论】:

      【解决方案5】:

      按两个不同的列单独分组会导致两个根本不同的查询,因此从数据库的角度来看,单独运行它们更容易。我会考虑创建两个索引(一个关于品牌,一个关于颜色)来提供帮助。

      【讨论】:

        【解决方案6】:

        可以使用 with 语句,但在编写此答案时 MySQL 中不可用。

        【讨论】:

        • 这仍然不会真正为您提供有用的结果集。您将获得与原始表一样多的行,其中恰好有该行的品牌和颜色的计数。然后你必须添加一个 group by,你可能会得到一个比单独运行选择更昂贵的查询。
        • 其实不然:over() 操作符使它相当于分别编写两个查询。但同样,在 MySQL 中不可用。
        • 虽然这些值是正确的,但您仍然会为每个返回的产品保留一行。
        【解决方案7】:
        $sql = "SELECT col_1, SUM(col_2), SUM(col_3) FROM table_name GROUP BY(col_1)";
        

        【讨论】:

        • 在总和处添加计数。这只是我刚刚在我的项目中看到的一个通用查询,可以在任何地方应用
        猜你喜欢
        • 2016-06-08
        • 2014-07-03
        • 1970-01-01
        • 2011-01-22
        • 1970-01-01
        • 2011-01-26
        • 2015-05-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多