2014-11-19 2 views
0

Я могу сделать это в Excel с помощью сводной таблицы, но я хотел бы выяснить способ сделать это непосредственно из одного SQL-запроса. Скажем, у меня есть список фруктов и их свежесть:SQL-запрос для возврата наиболее распространенных, 2-й наиболее распространенный, 3-й наиболее распространенный случай

**Fruit Freshness** 
Banana New 
Banana Ripe 
Apple Ripe 
Orange Old 
Cherry New 
Orange Ripe 
Apple Old 
Banana Old 
Apple New 
Apple New 
Orange Ripe 
Banana Old 
Orange New 
Cherry New 
Cherry Ripe 

Я хочу, чтобы считать «свежесть» вхождений затем ранжировать их, как наиболее часто, второй наиболее часто, и так далее. Результат будет выглядеть примерно так:

**Fruit Most common 2nd most common 3rd most common** 
Banana New   Old    Ripe 
Apple Old   New    Ripe 
Orange Ripe  New    Old 
Cherry New   Ripe   NA 

Возможно ли это в одном запросе?

+1

Редактировать ваши теги MySQL и SQL-сервера несовместимы. – Mihai

ответ

0

Вы можете просто использовать GROUP_CONCAT() агрегатную функцию:

SELECT 
    Fruit, GROUP_CONCAT(Freshness ORDER BY cnt DESC) as Common 
FROM (
    SELECT Fruit, Freshness, COUNT(*) cnt 
    FROM 
    fruits 
    GROUP BY 
    Fruit, Freshness 
) s 

, который будет возвращать значения, как:

Fruit | Common 
--------------------- 
Banana | New,Old,Ripe 
Cherry | New,Ripe 
... | ... 

, но если вы хотите, чтобы разделить результат в три столбца, вы можете объединить предыдущий запрос и использовать SUBSTRING_INDEX() для извлечения первого, сенкода и третьего значения из значений, разделенных запятой:

SELECT 
    Fruit, 
    SUBSTRING_INDEX(Common, ',', 1) AS most, 
    CASE WHEN CommonLIKE '%,%' 
     THEN SUBSTRING_INDEX(SUBSTRING_INDEX(Common, ',', 2), ',', -1) END AS second_most, 
    CASE WHEN CommonLIKE '%,%,%' 
     THEN SUBSTRING_INDEX(SUBSTRING_INDEX(Common, ',', 3), ',', -1) END AS third_most 
FROM (
    SELECT 
    Fruit, GROUP_CONCAT(Freshness ORDER BY cnt DESC) as Common 
    FROM (
    SELECT Fruit, Freshness, COUNT(*) cnt 
    FROM 
     fruits 
    GROUP BY 
     Fruit, Freshness 
) s 
    GROUP BY 
    Fruit 
) s 
0

SQL Server 2008 и выше:

select fruit, [1], [2], [3] from 
(select row_number() over (partition by fruit order by ct desc) as rn, fruit, freshness from (
select count(1) as ct, fruit, freshness from f 
group by fruit, freshness) g) src 
PIVOT 
(
MAX(Freshness) 
FOR rn in ([1], [2], [3]) 
) pvt 
0

Попробуйте

create table #fr (Fruit varchar(20), Freshness varchar(20)) 
insert #fr values 
('Banana' , 'New'),('Banana' , 'Ripe'),('Apple' , 'Ripe'),('Orange' , 'Old'),('Cherry' , 'New'), 
('Orange' , 'Ripe'),('Apple' , 'Old'),('Banana' , 'Old'),('Apple' , 'New'),('Apple' , 'New'), 
('Orange' , 'Ripe'),('Banana', 'Old'),('Orange' , 'New'),('Cherry', 'New'),('Cherry', 'Ripe') 


SELECT Fruit, 
     [1] Most_Common, 
     [2] Second_Common, 
     [3] Third_common 
FROM (SELECT Fruit,Freshness, 
       Row_number()OVER(partition BY Fruit ORDER BY Count(*) DESC) rn 
     FROM #fr 
     GROUP BY Fruit,Freshness) a 
     PIVOT (Max(Freshness) 
      FOR rn IN([1],[2],[3])) piv 
+0

Порядок Oooo по функции агрегации в окне, это хорошо, не знал об этом. –

+0

@KyleHale - Да, вы можете использовать его :) –

Смежные вопросы