【MYSQL分组查询前1或者前几名排名】

本文介绍五种SQL方法,用于从数据库表中选取每个名称对应的最高数值记录,包括使用子查询、联接、NOT EXISTS及聚合函数等技巧,适用于不同场景的数据筛选需求。

测试库表:

CREATE TABLE test(NAME VARCHAR(10),val INT,memo VARCHAR(20)); 
INSERT INTO test VALUES('a', 2, 'a2--a的第二个值') ;
INSERT INTO test VALUES('a', 1, 'a1--a的第一个值') ;
INSERT INTO test VALUES('a', 3, 'a3--a的第三个值') ;
INSERT INTO test VALUES('b', 1, 'b1--b的第一个值') ;
INSERT INTO test VALUES('b', 3, 'b3--b的第三个值') ;
INSERT INTO test VALUES('b', 2, 'b2--b的第二个值') ;
INSERT INTO test VALUES('b', 4, 'b2--b的第四个值') ;
INSERT INTO test VALUES('b', 5, 'b2--b的第五个值') ;
go

查询:

--方法1:
SELECT 
  a.* 
FROM
  test a 
WHERE val = 
  (SELECT 
    MAX(val) 
  FROM
    test 
  WHERE NAME = a.name) 
ORDER BY a.name; 
--方法2: 
SELECT 
  a.* 
FROM
  test a 
WHERE NOT EXISTS 
  (SELECT 
    1 
  FROM
    test 
  WHERE NAME = a.name 
    AND val > a.val);
解析:
整个这句话的作用是查询出字段val > a.val不存在于表test而只存在与表a(test)的所有记录
--方法3: 
SELECT 
  a.* 
FROM
  test a,
  (SELECT 
    NAME,
    MAX(val) val 
  FROM
    test 
  GROUP BY NAME) b 
WHERE a.name = b.name 
  AND a.val = b.val 
ORDER BY a.name ;
--方法4: 
SELECT 
  a.* 
FROM
  test a 
  INNER JOIN 
    (SELECT 
      NAME,
      MAX(val) val 
    FROM
      test 
    GROUP BY NAME) b 
    ON a.name = b.name 
    AND a.val = b.val 
ORDER BY a.name ;
--方法5 
SELECT 
  a.* 
FROM
  test a 
WHERE 1 > 
  (SELECT 
    COUNT(*) 
  FROM
    test 
  WHERE NAME = a.name 
    AND val > a.val) 
ORDER BY a.name;
类似查询:
select * from B where (select count(1) as num from A where A.ID = B.ID) = 0;
就是统计B表和A表用ID连接的行数
子查询的行数=0,就可以实现从B表中排除A表数据。
select * from B where (select count(1) as num from A where A.ID = B.ID) = 0;
分析
假设个例子吧:A表
id 姓名 性别
00 aa 女
01 bb 女
02 cc 女
B表
id 姓名 性别
00 aa 女
02 cc 女
03 dd 男
select * from B是执行B表,
当执行id=‘00’时 ,因为select count(1) as num from A where A.ID = B.ID 不等于0 所以运行结果没有第一行id=‘00’,
当执行id=‘02’时,因为select count(1) as num from A where A.ID = B.ID 不等于0 所以运行结果没有第二行id=‘02’,
当执行id= ‘03’时,因为select count(1) as num from A where A.ID = B.ID 的结果等于0 ,符合条件,所以运行结果会有第三行。
运行结果为:
id 姓名 性别
03 dd 男
所以:可以在B表中 排除A表的数据。

/* 
"name"	"val"	"memo"
"a"	"3"	"a3--a的第三个值"
"b"	"5"	"b2--b的第五个值"

*/

 

仅供参考

转载于:https://my.oschina.net/maojindaoGG/blog/2993732

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值