2015-12-25 2 views
3

У меня есть простая таблица, где я храню значение рыночной капитализации для кучи акций. Я пытаюсь увидеть, если я могу создать запрос, который будет возвращать что-то вроде следующего:mySQL: CASE, GROUP и ORDER By

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); 

ответ

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: ваш саз содержит тонкие ошибки (если вы пропустили и, и условия не имеют смысл, хотя формально правильно), вот правильный запрос (соответствует, когда условию остановки обработки):

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; 
+0

Это сделал трюк, спасибо! Теперь, когда я смотрю на SQL, я вижу, что делает оператор CASE, и как/где вызывать другие поля. – Gunnar

+0

@Gunnar, кстати, я скопировал и вставил ваш оператор CASE, и он содержит ошибки, я обновил ответ против правильного решения. – newtover

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(*) к вашему existsing запросу:

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
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.