Mysql 逐例分组语句

Mysql 逐例分组语句,mysql,database,Mysql,Database,我试图根据案例陈述进行分组,但运气不太好。我有一个orders表,我试图根据当月的总价值对订单进行分组,并根据其价值对订单进行分类 SELECT CASE WHEN sum(order_total_price) IS NULL THEN 'Unknown' WHEN sum(order_total_price) <= 1000 THEN 'Not more than 1,000'

我试图根据案例陈述进行分组,但运气不太好。我有一个orders表,我试图根据当月的总价值对订单进行分组,并根据其价值对订单进行分类

 SELECT 
      CASE
          WHEN sum(order_total_price) IS NULL
            THEN 'Unknown'
          WHEN sum(order_total_price) <= 1000
            THEN 'Not more than 1,000'
          WHEN sum(order_total_price) <= 2000
            THEN 'Between 1,001 and 2000'
          WHEN sum(order_total_price) <= 3000
            THEN 'Between 2001 and 3000'
          WHEN sum(order_total_price) <= 4000
            THEN 'Between 3001 and 4000'
          WHEN sum(order_total_price) <= 5000
            THEN 'Between 4001 and 5000'
          ELSE 'Over 5000'
        END
          AS  total_sales,
        COUNT(*) as total
      FROM orders
      WHERE YEAR(order_time)=2014 and MONTH(order_time)=07

      GROUP BY total_sales

这个的简写是

....
GROUP BY 1
使用输出列位置。否则,您必须在GROUPBY子句中重复整个案例块。

正如Jim Garrison所说

GROUP BY 1
那就最好了

另外,如果您对分组中的数字不满意,下面的方法也可以。将没有分组依据的原始查询作为内部查询。在外部查询中使用计数和分组依据

  SELECT A.TOTAL_SALES, COUNT(1) FROM
  (SELECT 
      CASE
          WHEN sum(order_total_price) IS NULL
            THEN 'Unknown'
          WHEN sum(order_total_price) <= 1000
            THEN 'Not more than 1,000'
          WHEN sum(order_total_price) <= 2000
            THEN 'Between 1,001 and 2000'
          WHEN sum(order_total_price) <= 3000
            THEN 'Between 2001 and 3000'
          WHEN sum(order_total_price) <= 4000
            THEN 'Between 3001 and 4000'
          WHEN sum(order_total_price) <= 5000
            THEN 'Between 4001 and 5000'
          ELSE 'Over 5000'
        END
          AS  total_sales       
      FROM orders
      WHERE YEAR(order_time)=2014 and MONTH(order_time)=07

      ) AS A
      GROUP BY A.total_sales

您的查询应该返回一行。运气与此无关。重要的是规格。除了SQL查询之外,还不清楚要返回什么结果集

我在猜测,这只是一个猜测,您希望返回多行,一行用于CASE表达式派生的每个订单大小类别

可能查询返回的结果集如下所示:

SELECT CASE
       WHEN o.order_total_price IS NULL
         THEN 'Unknown'
       WHEN o.order_total_price <= 1000
         THEN 'Not more than 1,000'
       WHEN o.order_total_price <= 2000
         THEN 'Between 1,001 and 2000'
       WHEN o.order_total_price <= 3000
         THEN 'Between 2001 and 3000'
       WHEN o.order_total_price <= 4000
         THEN 'Between 3001 and 4000'
       WHEN o.order_total_price <= 5000
         THEN 'Between 4001 and 5000'
         ELSE 'Over 5000'
       END AS order_value_category 
     , SUM(o.order_total_price) AS total_sales
     , COUNT(*) AS count_sales
  FROM orders o
 WHERE o.order_time >= '2014-07-01' 
   AND o.order_time <  '2014-07-01' + INTERVAL 1 MONTH
 GROUP BY order_value_category
为了提高性能,为了使MySQL能够使用合适的索引来满足order_time类别的谓词,我们需要在范围扫描谓词中引用bare order_time列


注意,GROUPBY子句意味着ORDERBY子句;如果希望按派生的order\u value\u category列以外的顺序返回行,则需要指定一个合适的order by子句。

如果使用GROUP by,则输出行将按照GROUP by列进行排序,就像对相同的列有order by一样。为避免按产品对该分组进行排序的开销,请按NULL添加ORDER:

按NULL顺序从测试_表组中选择a、COUNTb; 不推荐在MySQL 5.6中依靠隐式分组排序。要实现分组结果的特定排序顺序,最好使用显式ORDERBY子句。groupbysorting是一个MySQL扩展,在将来的版本中可能会发生变化;例如,使优化器能够以其认为最有效的方式对分组进行排序,并避免排序开销


运气与你无关。重要的是规格。我们希望这个问题中的查询只返回一行。如果它没有返回一行,那么很可能它返回了一个错误,尽管问题中没有提到错误。因此,我们只能猜测查询返回的结果集不满足某些尚未声明的需求。即使没有所需输出的示例,我们也只能猜测语句是否返回了错误,或者规范是什么。感谢您的帮助,解决方案成功了,我不得不在子查询中进行调整,并由客户进行修改。伟大的需要注意的一些潜在性能问题:WHERE子句中列上的函数使MySQL无法使用具有适当索引的索引范围扫描操作。此查询需要对表中的每一行进行完整扫描,以便对函数进行求值。其次,此查询要求MySQL将视图查询具体化为派生表,然后外部查询针对派生表运行。不需要中间派生表,也不需要进行完全扫描的查询也可以获得相同的结果。@spencer7593:我同意你的观点。在我的回答中,我已经清楚地提到使用列位置是最好的。我只是建议用另一种机制,也可以这样做!是的,MySQL允许SELECT列表中的表达式在SELECT列表中按位置在GROUP BY子句中引用,但也允许表达式通过其别名引用;我看不出用总销售额替换总销售额与用1替换总销售额有什么区别。嗯。。。MySQL似乎扩展了该标准,该标准不允许在此处使用别名。