SQL查询结果数据排序(二)

【SQL从一点一滴分析系列文章】为实际开发中的点点滴滴的总结,从最最简单的SQL 查询 到 综合分析查询
在分析 SQL 时,也会同时分析 mybatis 、Hibernate 中的相关操作
点击查看详情

本节讲述 对查询结果进行排序

1 以指定的次序返回查询结果

查询 用户表中所有用户的 姓名 年龄 地区,并按照年龄的升序排列,可以使用 order by 子句

select user_name,user_age,user_province 
    from t_user order by user_age asc 

使用 order by 子句,可以对结果集进行排序,默认情况下,order by 子句以升序方式排序,因此 asc 是可选的 ,desc 是表示降序的。
上述查询的结果,也可以这样写

select user_name,user_age,user_province 
    from t_user order by 2 asc 

这里使用了编号来实现排序的,那么在这里使用的2,是因为在我们的查询结果集中 user_name 占第1列,user_age 占第二列,这个编号是从1开始,依次从左到右依次对应查询结果集的每一列,如这里的2对应的就是 user_age。

2 按多个字段排序

查询 用户表中所有用户的 姓名 年龄 地区,并按照用户的编号升序排列,然后再按年龄的降序排列,我们可以如下写

select user_name,user_age,user_province ,user_id
    from t_user order by user_id asc ,user_age desc

在 order by 子句中列出不同的排列,可使用逗号分隔,在这里优先次序是从左到右。

3 按子串排序

查询用户表中所有的用户的姓名 年龄 地区详情,并且按照地区详情的前四个字符排序

在 DB2 MySQL Oracle PostgreSQL 中可以这样写

select user_name,user_age,user_address 
    from t_user order by substr(user_address,1,4)

substr()函数和hibernate的substr()参数都一样

substr(string string,num start,num length);
参数一 string为字符串;
参数二 start为起始位置;
参数三 length为长度。

所以在这里,substr(user_address,1,4),例如查出来的地址是 "山西省太原市八堡" ,通过 substr(user_address,1,4) 取出的标准就是 "山西省太"。
在 SQL Server 中可以这样写

select user_name,user_age,user_address 
    from t_user order by substring(user_address,1,4)

需要注意的是,这里的角标是从 1 开始的,在hibernate中substr()的start是从0开始的。

4 对字母数字混合的数据排序

对现有字母和数字的混合数据,希望按照数字或字符部分来rd排序
例如 我们查询用户的 姓名 编号 ,并将 姓名编号连接在一起返回到结果 集中

select user_name,user_id ,CONCAT(user_name,"",user_id) as msg  from t_user 
在这里插入图片描述

在 Oracle 和 PostgreSQL 中可以使用 函数 replace 和 translate 函数来修正 要排序的字条串,例如我们这里把查询到的结果集 msg 中的所有数字替换掉然后进行排序

select user_name,user_id ,CONCAT(user_name,"",user_id) as msg  from t_user 
order by
     replace(msg,
                replace(
                    translate(msg,'0123456789','#########'),
                   '#',
                   ''),
            '')

使用的函数为replace()
含义为:替换字符串
replace(原字段,“原字段旧内容“,“原字段新内容“,)

translate 与replace类似是替换函数,但translate是一次替换多个单个的字符。

我们这里把查询到的结果集 msg 中的所有的数字删除掉然后进行排序

select user_name,user_id ,CONCAT(user_name,"",user_id) as msg  from t_user 
order by
 replact( translate(msg,'0123456789','#'),'#','')

在 MySQL 和 SQL Server 中不支持 translate 函数。
replace 和 translate 函数从每一行中去掉数字或字符,这样就可以很容易的来进行排序。

5 处理排序中空值问题

例如我们在查询用户表的信息时,当根据用户的年龄来排序时,用户的年龄有空值,那么此时我们就需要处理这种情况,可以将空值的排列在最后,可以通过如下方式来处理

5.1 查询一
select user_name,user_age,user_id 
    from t_user

user_name user_age user_id
ceshi1 28 201
ceshi3 204
ceshi4 22 198
ceshi5 177
ceshi6 40 110
5. 2 查询二

DB2 MySQL PostgreSQL 和 SQL Server
使用 case 表达式来标记 一个值是否为 NULL ,这个标记有两个值,一个表示 NULL, 一个表示非 NULL 。这样只要在 order by 子句中增加标记列,便可以很容易的控制空值 是排列在前面还是最后面

select user_name,user_age,user_id 
    from ( select user_name,user_id,user_age,
                   case when user_age is null then 0
                   else 1
                   end
                   as is_null
          ) x
   order by is_null desc,user_age

user_name user_age user_id
ceshi3 22 198
ceshi3 28 201
ceshi3 40 110
ceshi3 177
ceshi5 204

在上述查询排序中,如果 user_age 为 null,那么标识列 is_null 的值为 0,否则为1,那么在 order by 中先 根据 is_null 倒序排列,所以 user_age 为null 是排列在最后的,然后再根据 user_age 进行二次排列

5. 3查询三
select user_name,user_age,user_id 
    from ( select user_name,user_id,user_age,
                   case when user_age is null then 0
                   else 1
                   end
                   as is_null
          ) x
   order by is_null desc,user_age desc

user_name user_age user_id
ceshi3 40 110
ceshi3 28 201
ceshi3 22 198
ceshi3 177
ceshi5 204

在这里与查询二 中的区别是 在 order by 中,user_age 又采用了倒序

5.4 查询四
select user_name,user_age,user_id 
    from ( select user_name,user_id,user_age,
                   case when user_age is null then 0
                   else 1
                   end
                   as is_null
          ) x
   order by is_null asc,user_age asc

user_name user_age user_id
ceshi3 177
ceshi5 204
ceshi3 22 198
ceshi3 28 201
ceshi3 40 110
6 根据数据项的键排序

在实际应用中,需要根据某些条件逻辑来排序,例如查询 用户表数据,user_province 如果是 北京 就用用户 user_age 来排序,否则根据 user_id 来排序
要实现这样的查询,我们可以在 order by 子句中使用 case 表达式

select user_name,user_age,user_id,user_province 
from t_user
order by case when user_province='北京' then user_age
         else user_id
         end

完结

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,204评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,091评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,548评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,657评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,689评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,554评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,302评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,216评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,661评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,851评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,977评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,697评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,306评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,898评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,019评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,138评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,927评论 2 355

推荐阅读更多精彩内容