mySQL:CASE,GROUP和ORDER By

时间:2015-12-25 18:58:53

标签: mysql group-by sql-order-by case

我有一个简单的表格,我存储了一堆股票的市值。我试图看看我是否可以创建一个返回类似以下内容的查询:

cap_type  type_count
micro     4
small     6
large     1
mega      2

我不确定如何调整此查询以计算不同选择案例组中的cap_types数量。这就是我到目前为止所拥有的:

SELECT CASE
    WHEN market_cap < 10 THEN 'micro' 
    WHEN market_cap >= 10 < 50 THEN 'small' 
    WHEN market_cap >= 50 < 100 THEN 'large' 
    ELSE 'mega' 
END AS cap_type
FROM stocks
GROUP BY CASE
    WHEN market_cap < 10 THEN 'micro' 
    WHEN market_cap >= 10 < 50 THEN 'small' 
    WHEN market_cap >= 50 < 100 THEN 'large' 
    ELSE 'mega' 
    END
ORDER BY cap_type ASC

以下是一些示例数据:

CREATE TABLE `stocks` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `stock` varchar(4) COLLATE utf8_unicode_ci DEFAULT NULL,
  `market_cap` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
)
INSERT INTO temp (`stock`,`market_cap`) VALUES ('MSFT', 40);
INSERT INTO temp (`stock`,`market_cap`) VALUES ('MINI', 4);
INSERT INTO temp (`stock`,`market_cap`) VALUES ('GOOG', 50);
INSERT INTO temp (`stock`,`market_cap`) VALUES ('F', 90);

3 个答案:

答案 0 :(得分:1)

您可以使用子查询:

SELECT sub.cap_type, COUNT(*) AS type_count
FROM (
    SELECT CASE WHEN market_cap < 10 THEN 'micro' 
                WHEN market_cap < 50 THEN 'small' 
                WHEN market_cap < 100 THEN 'large' 
                ELSE 'mega' 
           END AS cap_type
    FROM temp
) AS sub  
GROUP BY sub.cap_type
ORDER BY 
CASE sub.cap_type
  WHEN 'micro' THEN 1
  WHEN 'small' THEN 2
  WHEN 'large' THEN 3
  ELSE 4
END;

SqlFiddleDemo

或仅向您现有的查询添加COUNT(*)

SELECT CASE WHEN market_cap < 10 THEN 'micro' 
            WHEN market_cap < 50 THEN 'small' 
            WHEN market_cap < 100 THEN 'large' 
            ELSE 'mega'
       END AS cap_type
       ,COUNT(*) AS type_count
FROM temp
GROUP BY CASE WHEN market_cap < 10 THEN 'micro' 
              WHEN market_cap < 50 THEN 'small' 
              WHEN market_cap < 100 THEN 'large' 
              ELSE 'mega' 
          END
ORDER BY 
CASE cap_type
  WHEN 'micro' THEN 1
  WHEN 'small' THEN 2
  WHEN 'large' THEN 3
  ELSE 4
END

如果您需要所有组,可以使用子查询列出它们并LEFT JOIN

SELECT sub.cap_type, COUNT(t.market_cap) AS type_count
FROM (SELECT 'micro' AS cap_type
      UNION ALL SELECT 'small'
      UNION ALL SELECT 'large' 
      UNION ALL SELECT 'mega') AS sub
LEFT JOIN temp t
  ON CASE
    WHEN t.market_cap < 10 THEN 'micro' 
    WHEN t.market_cap < 50 THEN 'small' 
    WHEN t.market_cap < 100 THEN 'large' 
    ELSE 'mega' 
    END = sub.cap_type
GROUP BY sub.cap_type
ORDER BY 
  CASE cap_type
    WHEN 'micro' THEN 1
    WHEN 'small' THEN 2
    WHEN 'large' THEN 3
    ELSE 4
  END

SqlFiddleDemo2

输出:

╔═══════════╦════════════╗
║ cap_type  ║ type_count ║
╠═══════════╬════════════╣
║ micro     ║          1 ║
║ small     ║          1 ║
║ large     ║          2 ║
║ mega      ║          0 ║
╚═══════════╩════════════╝   

答案 1 :(得分:1)

您是否尝试过以下操作?或者我是否理解错误的问题?

SELECT 
  CASE
    WHEN market_cap < 10 THEN 'micro' 
    WHEN market_cap >= 10 < 50 THEN 'small' 
    WHEN market_cap >= 50 < 100 THEN 'large' 
    ELSE 'mega' 
  END AS cap_type,
  COUNT(*) as count
FROM stocks
GROUP BY cap_type
ORDER BY cap_type ASC;

UPD:您的CASE语句包含细微错误(您错过了AND,条件没有意义,但形式上是正确的),这是正确的查询(匹配WHEN条件停止处理):

SELECT 
  CASE
    WHEN market_cap < 10 THEN 'micro' 
    WHEN market_cap < 50 THEN 'small' 
    WHEN market_cap < 100 THEN 'large' 
    ELSE 'mega' 
  END AS cap_type,
  COUNT(*) as count
FROM stocks
GROUP BY cap_type
ORDER BY cap_type ASC;

答案 2 :(得分:1)

SELECT 
CASE
    WHEN market_cap < 10 THEN 'micro'
    WHEN market_cap >= 10 and market_cap < 50 THEN 'small'
    WHEN market_cap >= 50 and market_cap < 100 THEN 'large'
    ELSE 'mega'
END AS cap_type,
count(*)
FROM stock
GROUP BY CASE
    WHEN market_cap < 10 THEN 'micro'
    WHEN market_cap >= 10 and market_cap < 50 THEN 'small'
    WHEN market_cap >= 50 and market_cap < 100 THEN 'large'
    ELSE 'mega'
END
ORDER BY cap_type ASC;

SQLFiddle.