I can do this in Excel using a pivot table, but I'd like to figure out a way to do this directly from a single SQL query. Let's say I have a list of fruits and their freshness:
**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
I want to count the "freshness" occurrences then rank them as the most frequent, 2nd most frequent, and so on. The result would look something like this:
**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
Is this possible in one query?
You can just use GROUP_CONCAT() aggregate function:
SELECT
Fruit, GROUP_CONCAT(Freshness ORDER BY cnt DESC) as Common
FROM (
SELECT Fruit, Freshness, COUNT(*) cnt
FROM
fruits
GROUP BY
Fruit, Freshness
) s
that will return values like:
Fruit | Common
---------------------
Banana | New,Old,Ripe
Cherry | New,Ripe
... | ...
but if you want to divide the result in three columns, you can combine the previous query and use SUBSTRING_INDEX() to extract the first, sencond, and third value from the comma separated values:
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
SQL Server 2008 and up:
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
Try this
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.