Reputation: 2169
I have a mysql table with 3 fields Brand,Model and BenchMark Score.
Notes regarding how the data will be in this table.
1.A brand can have different models. 2.Different Brands can have models will same name 3.There can be different Benchmark score of the a particular brand-model combination.
So the table data will look something like this
Brand ModelName Benchmark
B1 M1 1000
B1 M1 2000
B1 M2 3000
B1 M2 2000
B2 M1 3000
B2 M3 4000
Now what i need is to find is the number of time a particular benchmark score is reported.
Here we should count only those benchmark score which is the maximum for a model-brand combination and not all those benchmark scores.
The result should be like this
Score Times
3000 2
2000 1
4000 1
So what should be the mysql statement if i need this result..please help
Upvotes: 2
Views: 753
Reputation: 44343
SELECT * FROM
(SELECT MX,COUNT(1) SC FROM
(SELECT MAX(MaxScores.MaxScore) MX,ScoreCounts.ScoreCount FROM
(
SELECT MAX(BenchMark) MaxScore,Brand,ModelName
FROM benchmarks GROUP BY Brand,ModelName
) MaxScores
INNER JOIN
(
SELECT COUNT(1) ScoreCount,Brand,ModelName
FROM benchmarks GROUP BY Brand,ModelName
) ScoreCounts
USING (Brand,ModelName)
GROUP BY Brand,ModelName
) A GROUP BY MX) AA ORDER BY SC DESC,MX;
This query produced exactly what you are looking for and displays the result in the exact order your question has it. I tried it out with your sample data from the question. Here is what I got:
mysql> use test
Database changed
mysql> drop table if exists benchmarks;
Query OK, 0 rows affected (0.05 sec)
mysql> CREATE TABLE benchmarks (Brand CHAR(2),ModelName CHAR(2),BenchMark INT,key (Brand,ModelName));
Query OK, 0 rows affected (0.14 sec)
mysql> INSERT INTO benchmarks VALUES
-> ('B1','M1',1000),
-> ('B1','M1',2000),
-> ('B1','M2',3000),
-> ('B1','M2',2000),
-> ('B2','M1',3000),
-> ('B2','M3',4000);
Query OK, 6 rows affected (0.03 sec)
Records: 6 Duplicates: 0 Warnings: 0
mysql> SHOW CREATE TABLE benchmarks\G
*************************** 1. row ***************************
Table: benchmarks
Create Table: CREATE TABLE `benchmarks` (
`Brand` char(2) DEFAULT NULL,
`ModelName` char(2) DEFAULT NULL,
`BenchMark` int(11) DEFAULT NULL,
KEY `Brand` (`Brand`,`ModelName`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
mysql> SELECT * FROM benchmarks;
+-------+-----------+-----------+
| Brand | ModelName | BenchMark |
+-------+-----------+-----------+
| B1 | M1 | 1000 |
| B1 | M1 | 2000 |
| B1 | M2 | 3000 |
| B1 | M2 | 2000 |
| B2 | M1 | 3000 |
| B2 | M3 | 4000 |
+-------+-----------+-----------+
6 rows in set (0.01 sec)
mysql> SELECT * FROM
-> (SELECT MX,COUNT(1) SC FROM
-> (SELECT MAX(MaxScores.MaxScore) MX,ScoreCounts.ScoreCount FROM
-> (
-> SELECT MAX(BenchMark) MaxScore,Brand,ModelName
-> FROM benchmarks GROUP BY Brand,ModelName
-> ) MaxScores
-> INNER JOIN
-> (
-> SELECT COUNT(1) ScoreCount,Brand,ModelName
-> FROM benchmarks GROUP BY Brand,ModelName
-> ) ScoreCounts
-> USING (Brand,ModelName)
-> GROUP BY Brand,ModelName
-> ) A GROUP BY MX) AA ORDER BY SC DESC,MX;
+------+----+
| MX | SC |
+------+----+
| 3000 | 2 |
| 2000 | 1 |
| 4000 | 1 |
+------+----+
3 rows in set (0.01 sec)
Give it a Try !!!
Upvotes: 3
Reputation: 425371
SELECT b.model, b.brand, bd.score, COUNT(*)
FROM (
SELECT model, brand, MAX(score) AS mscore
FROM benchmark
GROUP BY
model, brand
) bd
JOIN benchmark b
ON b.model = bd.model
AND b.brand = bd.brand
AND b.score = bd.mscore
GROUP BY
b.model, b.brand
Create an index on (model, brand, score)
for this to work fast.
Update:
SELECT score, COUNT(*) AS cnt
FROM benchmark
GROUP BY
score
ORDER BY
cnt DESC
Upvotes: 0