显示基于max(列)结果MySQL的特定列

时间:2014-09-28 17:46:52

标签: mysql sql greatest-n-per-group

我有一张名为'nilai'的表,这里是整个内容

mysql> select * from nilai;
+------------+------+-----------------+-------+
| nim        | nama | matkul          | nilai |
+------------+------+-----------------+-------+
| 0911500101 | ADI  | ALGORITMA       |    90 |
| 0911500101 | ADI  | KALKULUS        |    65 |
| 0911500101 | ADI  | PBO             |    90 |
| 0911500101 | ADI  | PEMROGRAMAN WEB |    90 |
| 0911500101 | ADI  | PTI             |    75 |
| 0911500102 | IDA  | ALGORITMA       |    80 |
| 0911500102 | IDA  | KALKULUS        |    70 |
| 0911500102 | IDA  | PBO             |    80 |
| 0911500102 | IDA  | PEMROGRAMAN WEB |    85 |
| 0911500102 | IDA  | PTI             |    90 |
| 0911500103 | EDI  | ALGORITMA       |    85 |
| 0911500103 | EDI  | KALKULUS        |    60 |
| 0911500103 | EDI  | PBO             |    85 |
| 0911500103 | EDI  | PEMROGRAMAN WEB |    85 |
| 0911500103 | EDI  | PTI             |    88 |
| 0911500104 | INA  | ALGORITMA       |    75 |
| 0911500104 | INA  | KALKULUS        |    50 |
| 0911500104 | INA  | PBO             |    75 |
| 0911500104 | INA  | PEMROGRAMAN WEB |    80 |
| 0911500104 | INA  | PTI             |    72 |
| 0911500105 | ANI  | ALGORITMA       |    92 |
| 0911500105 | ANI  | KALKULUS        |    68 |
| 0911500105 | ANI  | PBO             |    80 |
| 0911500105 | ANI  | PEMROGRAMAN WEB |    92 |
| 0911500105 | ANI  | PTI             |    90 |
+------------+------+-----------------+-------+
25 rows in set (0.00 sec)

我想为每个'matkul'(或英语,科目)展示'max(nilai)'和'min(nilai)',所以我创建了一个这样的查询,它完美地运作了:

mysql> select matkul, min(nilai), max(nilai) from nilai group by matkul;
+-----------------+------------+------------+
| matkul          | min(nilai) | max(nilai) |
+-----------------+------------+------------+
| ALGORITMA       |         75 |         92 |
| KALKULUS        |         50 |         70 |
| PBO             |         75 |         90 |
| PEMROGRAMAN WEB |         80 |         92 |
| PTI             |         72 |         90 |
+-----------------+------------+------------+
5 rows in set (0.03 sec)

但是那个查询只显示了max(nilai)和min(nilai)而没有显示max(nilai)和min(nilai)属于谁,所以最终结果将是这样的

+-----------------+------------+------------+----------------+----------------+
| matkul          | min(nilai) | max(nilai) | min belongs to | max belongs to |
+-----------------+------------+------------+----------------+----------------+
| ALGORITMA       |         75 |         92 |            INA |            ANI |
| KALKULUS        |         50 |         70 |            INA |            IDA |
| PBO             |         75 |         90 |            INA |            ADI |
| PEMROGRAMAN WEB |         80 |         92 |            INA |            ANI |
| PTI             |         72 |         90 |            INA |      ANI / IDA |
+-----------------+------------+------------+----------------+----------------+
5 rows in set (0.03 sec)

所以我提出了很多疑问,但没有人有效,其中两个是:

mysql> select matkul, max(nilai), nama from nilai group by matkul;
+-----------------+------------+------+
| matkul          | max(nilai) | nama |
+-----------------+------------+------+
| ALGORITMA       |         92 | ADI  |
| KALKULUS        |         70 | ADI  |
| PBO             |         90 | ADI  |
| PEMROGRAMAN WEB |         92 | ADI  |
| PTI             |         90 | ADI  |
+-----------------+------------+------+
5 rows in set (0.00 sec)

和这个

mysql> select matkul, (select nama from nilai having max(nilai) as maxname), (select   
nama from nilai having min(nilai) as minname) from nilai group by matkul;

+-----------------+---------+---------+
| matkul          | maxname | minname |
+-----------------+---------+---------+
| ALGORITMA       | ADI     | ADI     |
| KALKULUS        | ADI     | ADI     |
| PBO             | ADI     | ADI     |
| PEMROGRAMAN WEB | ADI     | ADI     |
| PTI             | ADI     | ADI     |
+-----------------+---------+---------+
5 rows in set (0.08 sec)

那我怎么能把它全部搞定,请给我建议,先谢谢! :d

4 个答案:

答案 0 :(得分:1)

在MySQL中,我认为最简单的方法是使用substring_index() / group_concat()技巧:

select matkul, min(nilai), max(nilai),
       substring_index(group_concat(nama order by nilai asc), ',', 1) as min_nama,
       substring_index(group_concat(nama order by nilai desc), ',', 1) as max_nama
from nilai
group by matkul;

如果您有许多具有相同主题的学生,那么您可能会遇到字符串长度的问题。此外,您只能获得一个学生姓名。

如果这是一个问题,您可以使用相关子查询或连接:

select matkul, min(nilai), max(nilai),
       (select nama from nilai n2 where n2.matkul = n.matkul order by nilai asc limit 1) as min_nama,
       (select nama from nilai n2 where n2.matkul = n.matkul order by nilai desc limit 1) as max_nama
from nilai n
group by matkul;

答案 1 :(得分:0)

| PTI             |         72 |         90 |            INA |      ANI / IDA |

如果min belongs tomax belongs to中存在关联,您似乎想要返回多个学生。您可以通过从派生表中进行选择来实现此目的,其中每行包含每个主题和分数的学生列表,并将这些分数与您的最大/最小分数相结合。

select t1.matkul, t1.min_nilai, t1.max_nilai, 
       t2.min_belongs_to, t3.max_belongs_to
from (
    select matkul, min(nilai) min_nilai, max(nilai) max_nilai
    from nilai group by matkul
) t1 
join (
    select nilai, matkul, group_concat(nama) min_belongs_to 
    from nilai group by nilai, matkul
) t2 on t1.min_nilai = t2.nilai and t1.matkul = t2.matkul
join (
    select nilai, matkul, group_concat(nama) max_belongs_to 
    from nilai group by nilai, matkul
) t3 on t1.max_nilai = t3.nilai and t1.matkul = t3.matkul

答案 2 :(得分:0)

一种方法 - 如果你想要显示关系,将查询拆分为两个查询的联合 - 一个用于min,一个用于max - 和一个外部查询来组合它们;

SELECT matkul, MIN(nilai), MAX(nilai), MIN(nama_min), MAX(nama_max) FROM (
  SELECT matkul, nilai, null nama_min, GROUP_CONCAT(nama SEPARATOR ' / ') nama_max 
  FROM nilai n1
  WHERE NOT EXISTS(
    SELECT 1 FROM nilai n2 WHERE n1.matkul = n2.matkul AND n1.nilai < n2.nilai
  )
  GROUP BY matkul
  UNION ALL
  SELECT matkul, nilai, GROUP_CONCAT(nama SEPARATOR ' / ') nama_min, null 
  FROM nilai n1
  WHERE NOT EXISTS(
    SELECT 1 FROM nilai n2 WHERE n1.matkul = n2.matkul AND n1.nilai > n2.nilai
  )
  GROUP BY matkul
)z
GROUP BY matkul;

An SQLfiddle to test with

答案 3 :(得分:0)

select matkul, min(nilai) nilaiMIN, max(nilai) naliMAX
,(select nama from nilai where nilai = (select min(nilai) from nilai  where matkul = n.matkul))         namaMIN
,(select nama from nilai where nilai = (select max(nilai) from nilai  where matkul = n.matkul)) namaMAX
 from nilai n group by matkul