关于order by的用法

今天在逛论坛的时候看到shiyiwan同学写了一个很简单的语句,可是order by后面的形式却比较新颖(对于我来说哦),以前从来没看过这种用法,就想记下来,正好总结一下ORDER BY的知识。

1、ORDER BY 中关于NULL的处理

缺省处理,Oracle在Order by 时认为null是最大值,所以如果是ASC升序则排在最后,DESC降序则排在最前。

当然,你也可以使用nulls first 或者nulls last 语法来控制NULL的位置。
Nulls first和nulls last是Oracle Order by支持的语法
如果Order by 中指定了表达式Nulls first则表示null值的记录将排在最前(不管是asc 还是 desc)
如果Order by 中指定了表达式Nulls last则表示null值的记录将排在最后 (不管是asc 还是 desc)
使用语法如下:
--将nulls始终放在最前
select * from zl_cbqc order by cb_ld nulls first
--将nulls始终放在最后
select * from zl_cbqc order by cb_ld desc nulls last

2、几种排序的写法
单列升序:select<column_name> from <table_name> order by <column_name>; (默认升序,即使不写ASC)

单列降序:select <column_name> from <table_name> order by <column_name> desc;
多列升序:select <column_one>, <column_two> from <table_name> order by <column_one>, <column_two>;
多列降序:select <column_one>, <column_two> from <table_name> order by <column_one> desc, <column_two> desc;
多列混合排序:select <column_one>, <column_two> from <table_name> order by <column_one> desc, <column_two> asc;

3、今天看到的新写法

SQL> select * from tb;

    BLOGID BLOGCLASS
---------- ------------------------------
        1 人生
        2 学习
        3 工作
        5 朋友

SQL> select * from tb order by decode(blogid,3,1,2), blogid;

    BLOGID BLOGCLASS
---------- ------------------------------
        3 工作
        1 人生
        2 学习
        5 朋友

我所说的就是上面红色的那句话。实现的功能就是不管怎样,BLOGID为3的值必须排在第一位,其他的记录按照BLOGID升序排序。

shiyiwan同学给我的解释是这样的:“默认升序排序,blogid = 3时返回1,其他则返回2, 所以blogid = 3的记录排在最前啊。”

wildwave同学也给了个说法:“你将那个decode理解成前面select后面的列,按照那一列排序就好了。”

我又去试了一条语句,结果如下

SQL>  select * from tb order by decode(blogid,3,1,2);

    BLOGID BLOGCLASS
---------- ------------------------------
         3 工作
         5 朋友
         1 人生
         2 学习

我现在的理解是这样的,通过decode()函数,BLOGID值为3的那条记录被转换为了1,而其他的记录都是2,那么按照这个顺序排序,肯定BLOGID为3的那条记录永远在最前面了,不仅如此,注意到后面还加了个按BLOGID默认升序排列,这也就是说对于那些被DECODE转换为2的记录来说,按照它们的BLOGID升序排序。

呵呵,也不知道对不对,至少现在我是这么理解的,先记下来吧。

转载地址:http://blog.sina.com.cn/s/blog_7582409f0100qdpa.html


<think>嗯,用户想了解SQL中GROUP BY、HAVING和ORDER BY用法,需要提供示例教程。首先,我需要回顾这些关键字的基本功能和执行顺序。根据引用[1],GROUP BY必须在WHERE之后,ORDER BY之前,而HAVING是在GROUP BY之后用来过滤分组。 首先,应该从GROUP BY开始解释。GROUP BY用于将数据按指定列分组,通常与聚合函数如SUM、COUNT一起使用。例如,引用[2]中的示例展示了按Customer分组并计算订单总价。需要详细说明这个例子,并可能添加更多例子,比如按地区或产品类别分组。 接下来是HAVING,它与WHERE的区别在于,WHERE过滤行,而HAVING过滤分组后的结果。比如,选择总订单金额超过1000的客户。需要强调HAVING必须跟在GROUP BY之后,并且可以使用聚合函数作为条件。 然后是ORDER BY,用于排序结果集,可以指定升序或降序。例如,按总订单金额降序排列。这里要注意ORDER BY在SELECT之后执行,所以可以使用别名。 执行顺序是关键。根据引用[1],顺序是WHERE → GROUP BY → HAVING → ORDER BY。需要明确说明每个步骤的作用,比如先过滤行,再分组,再过滤分组,最后排序。 需要提供综合示例,将这三个子句结合起来使用,比如先筛选状态为“已发货”的订单,按客户分组,筛选总金额超过500的,最后按总金额排序。这样用户能清楚看到整个流程。 可能还需要常见问题解答,比如能否在GROUP BY中使用别名,或者HAVING能否不使用聚合函数。根据引用[3],GROUP BY处理的是原始列名,而HAVING通常涉及聚合条件,但也可以有其他条件。 最后,生成相关问题,帮助用户进一步学习,比如执行顺序、优化技巧或性能影响。确保回答结构清晰,分步骤讲解,并附上代码示例,让用户容易理解。</think>以下是对SQL中GROUP BY、HAVING和ORDER BY用法解析,结合执行顺序和实际示例说明: --- ### 一、核心功能与执行顺序 根据SQL标准,关键子句的执行顺序为: $$ \text{WHERE} \rightarrow \text{GROUP BY} \rightarrow \text{HAVING} \rightarrow \text{ORDER BY} $$ 这意味着: 1. **WHERE**先过滤原始数据行 2. **GROUP BY**对过滤后的数据分组 3. **HAVING**筛选分组结果 4. **ORDER BY**对最终结果排序[^1] --- ### 二、GROUP BY 分组聚合 **功能**:将数据按指定列分组,常与聚合函数(SUM/COUNT/AVG等)联用 **语法**: ```sql SELECT 列1, 聚合函数(列2) FROM 表名 GROUP BY 列1 ``` **示例**:统计每个客户的订单总金额 ```sql SELECT Customer, SUM(OrderPrice) AS Total FROM Orders GROUP BY Customer ``` 结果会按Customer分组,显示每个客户的消费总额[^2] --- ### 三、HAVING 分组过滤 **功能**:对GROUP BY的分组结果进行筛选(类似于WHERE对行的过滤) **注意**:HAVING必须与GROUP BY联用,且条件中可包含聚合函数 **示例**:筛选总订单金额超过$1000的客户 ```sql SELECT Customer, SUM(OrderPrice) AS Total FROM Orders GROUP BY Customer HAVING SUM(OrderPrice) > 1000 ``` --- ### 四、ORDER BY 结果排序 **功能**:对最终结果按指定列排序 **语法**: ```sql ORDER BY 列名 [ASC|DESC] ``` **示例**:按消费总额降序排列 ```sql SELECT Customer, SUM(OrderPrice) AS Total FROM Orders GROUP BY Customer HAVING Total > 1000 ORDER BY Total DESC ``` *注意:ORDER BY可以使用SELECT中定义的别名[^3]* --- ### 五、综合应用示例 查询2023年订单中,总消费超过$500且订单数≥3的客户,按消费额降序排列: ```sql SELECT Customer, COUNT(*) AS OrderCount, SUM(OrderPrice) AS TotalSpent FROM Orders WHERE OrderDate BETWEEN '2023-01-01' AND '2023-12-31' GROUP BY Customer HAVING TotalSpent > 500 AND OrderCount >= 3 ORDER BY TotalSpent DESC ``` --- ### 六、常见问题 1. **GROUP BY能否使用列别名?** 不行!GROUP BY处理阶段SELECT尚未执行,需使用原始列名 2. **HAVING能否不使用聚合函数?** 可以,但此时等效于WHERE过滤(效率更低) 3. **多列分组如何操作?** ```sql GROUP BY Country, City -- 先按国家分组,再按城市细分 ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值