那些年很迷的sql

本文深入探讨了SQL中distinct关键字的正确使用方法,包括如何避免常见陷阱;介绍了如何更新表字段值,以及group_concat函数的使用技巧,特别是处理NULL值的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、distinct:

sql: select * from user

这里写图片描述

为了对username去重:

sql: select distinct username from user

这里写图片描述

为了对username去重,并且查询其他字段:

sql: select distinct username, usertype,userpassword from user

这里写图片描述

问题出现了: distinct 之后还要查询其他字段的时候,distinct 不起作用了

sql: select distinct username, usertype,userpassword from user group by username

这里写图片描述

sql: select distinct username, usertype,userpassword from user group by userpassword

这里写图片描述

sql: select distinct username, userpassword from user

这里写图片描述

分析:

group by username之后确实对username去重了,但是group by userpassword之后只去重了username相同并且userpassword相同的记录,如果没有group by 的话distinct将会对username和userpassword全部相同的进行去重

猜想:

可能在存在distinct的查询语句中,如果想查询distinct之外的其他字段,并且结果中不能有这个字段的相同之,就必须group by与distinct相同的字段

2、将一张表的一个字段赋值给另一张表的一个字段:

sql: update cs_user r set r.username=(select h.tel2 from cs_human h where h.id=r.objid and h.deleted=0) and r.deleted=0

问题出现了: 我想做的是将cs_human表中的tel2字段赋值给cs_user表中的username,但是执行完上面的sql后,cs_user表中的username字段全变成0或者1了。。。之后就换了一种写法,就实现了。。。
sql: update cs_user r,cs_human h set r.username =h.tel2 where r.objid=h.id

3、group_concat(oracle中的wm_concat):

sql脚本:

DROP TABLE IF EXISTS `test1`;
CREATE TABLE `test1` (
  `id` varchar(32) DEFAULT NULL,
  `name` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of test1
-- ----------------------------
INSERT INTO `test1` VALUES ('1', '小明');
INSERT INTO `test1` VALUES ('2', '小红');

-- ----------------------------
-- Table structure for test2
-- ----------------------------
DROP TABLE IF EXISTS `test2`;
CREATE TABLE `test2` (
  `id` varchar(255) DEFAULT NULL,
  `tel` varchar(255) DEFAULT NULL,
  `testid` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of test2
-- ----------------------------
INSERT INTO `test2` VALUES ('1', '9', '1');
INSERT INTO `test2` VALUES ('2', null, '1');
INSERT INTO `test2` VALUES ('3', '8', '1');
INSERT INTO `test2` VALUES ('4', '7', '2');

① group by 问题:如果group_concat(字段1)之后不group by的话,结果永远只有一条记录,他会将所有的字段1(有值的字段1,没值的字段1直接被忽略)用,拼接起来组成一个查询结果字段

SELECT t.id, GROUP_CONCAT(tt.tel) FROM test1 t LEFT JOIN test2 tt on t.id=tt.testid 

这里写图片描述

加上group by之后:

SELECT t.id, GROUP_CONCAT(tt.tel) FROM test1 t LEFT JOIN test2 tt on t.id=tt.testid GROUP BY t.id

这里写图片描述

② null值问题:不知道各位观众老爷有没有发现一个问题,就是上面的查询结果是不是应该要是8,,9呢,而不应该是8,9???是的,group_concat这个函数他自己是忽略null值的,如果他遇到null值就会直接跳过。

解决方法:还记不记得在 https://blog.youkuaiyun.com/tuesdayma/article/details/78414511 中提到过的ifnull函数(oracle中的nvl()函数),他就能解决null值问题。而且不存在顺序问题(即如果两个字段都是用了这个函数,他们的结果拼接顺序是一样的)

SELECT t.id, GROUP_CONCAT(ifnull(tt.id,'-'))ids  ,GROUP_CONCAT(ifnull(tt.tel,'-')) tel FROM test1 t LEFT JOIN test2 tt on t.id=tt.testid GROUP BY t.id

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值