您好!欢迎访问家园网-www.jy.wang!

家园网

SQL 自连接排名查询

网络 作者:本站 点击:

SELECT (SELECT COUNT(order_id) FROM orderform A
WHERE A.order_id>=B.order_id) 编号,order_id,order_sn,total_amount
FROM orderform B ORDER BY 1;


SQL 自连接排名查询代码重新讲解


一、代码整体结构

sql

SELECT 
    (SELECT COUNT(order_id) 
     FROM orderform A     WHERE A.order_id >= B.order_id) 编号,
    order_id,
    order_sn,
    total_amountFROM orderform B 
ORDER BY 1;


二、这段代码的作用

按 order_id 从大到小生成排名编号(编号越小排名越高)

排名order_id说明
1最大的 order_id第1名
2第二大的 order_id第2名
3第三大的 order_id第3名
.........

三、逐部分讲解

第1-4行:子查询(核心排名逻辑)

sql

(SELECT COUNT(order_id) 
 FROM orderform A WHERE A.order_id >= B.order_id) 编号

这是一个相关子查询(Correlated Subquery),为外层查询的每一行计算一个排名编号。

部分含义
SELECT COUNT(order_id)统计符合条件的订单数量
FROM orderform A给内层表起别名 A
WHERE A.order_id >= B.order_id统计 order_id 大于等于当前行 order_id 的记录数
) 编号子查询结束,将结果列命名为"编号"

第5行:外层查询的字段

sql

order_id, order_sn, total_amount

字段含义
order_id订单编号
order_sn订单流水号
total_amount订单总金额

第6行:数据来源与排序

sql

FROM orderform B 
ORDER BY 1;

部分含义
FROM orderform B从订单表查询,起别名 B
ORDER BY 1按查询结果的第1列(即"编号"列)升序排序

四、核心原理:相关子查询如何计算排名?

假设原表数据

order_id

order_sn

total_amount

1

SN001

100

2

SN002

200

3

SN003

150

4

SN004

300

执行过程

外层查询逐行读取 orderform B,每读一行,就执行一次子查询:

第1行:B.order_id = 1

sql

SELECT COUNT(order_id) FROM orderform A WHERE A.order_id >= 1

  • 统计 order_id >= 1 的记录数

  • 符合条件的 order_id:1、2、3、4 → 共 4 条

  • 子查询结果:4

第2行:B.order_id = 2

sql

SELECT COUNT(order_id) FROM orderform A WHERE A.order_id >= 2

  • 符合条件的 order_id:2、3、4 → 共 3 条

  • 子查询结果:3

第3行:B.order_id = 3

  • 符合条件的 order_id:3、4 → 共 2 条

第4行:B.order_id = 4

  • 符合条件的 order_id:4 → 共 1 条


五、计算后的中间结果(未排序)

编号(计算值)

order_id

order_sn

total_amount

4

1

SN001

100

3

2

SN002

200

2

3

SN003

150

1

4

SN004

300



此时编号是倒序的:order_id 越大,编号越小(因为满足 >= 条件的记录越少)。


六、ORDER BY 1 排序后的最终结果

ORDER BY 1 按第1列(编号)升序排序后:

编号

order_id

order_sn

total_amount

1

4

SN004

300

2

3

SN003

150

3

2

SN002

200

4

1

SN001

100


最终效果

  • 编号从小到大:1、2、3、4

  • order_id 从大到小:4、3、2、1

  • 编号 = 排名(1是最高排名,对应最大的 order_id)


七、完整执行流程图

text

┌─────────────────────────────────────────────────────────────┐
│  步骤1:外层查询逐行读取,内层子查询计算编号                 │
├─────────────────────────────────────────────────────────────┤
│  B.order_id=1 → 子查询统计 >=1 → 结果=4 → (4,1,SN001,100)  │
│  B.order_id=2 → 子查询统计 >=2 → 结果=3 → (3,2,SN002,200)  │
│  B.order_id=3 → 子查询统计 >=3 → 结果=2 → (2,3,SN003,150)  │
│  B.order_id=4 → 子查询统计 >=4 → 结果=1 → (1,4,SN004,300)  │
└─────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────┐
│  步骤2:ORDER BY 1 按编号列升序排序                          │
├─────────────────────────────────────────────────────────────┤
│  编号=1 → (1,4,SN004,300)                                  │
│  编号=2 → (2,3,SN003,150)                                  │
│  编号=3 → (3,2,SN002,200)                                  │
│  编号=4 → (4,1,SN001,100)                                  │
└─────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────┐
│  最终结果                                                   │
├─────────────────────────────────────────────────────────────┤
│  编号=1(最高排名)对应 order_id=4(最大订单号)            │
│  编号=2 对应 order_id=3                                     │
│  编号=3 对应 order_id=2                                     │
│  编号=4 对应 order_id=1(最小订单号)                       │
└─────────────────────────────────────────────────────────────┘


八、如何改为正序排名(order_id 从小到大编号为1)?

只需把 >= 改为 <=

sql

SELECT 
    (SELECT COUNT(order_id) FROM orderform A     WHERE A.order_id <= B.order_id) 编号,
    order_id,
    order_sn,
    total_amountFROM orderform B 
ORDER BY 1;

结果

编号order_id
11
22
33
44

九、ORDER BY 1 的含义

写法含义
ORDER BY 1按 SELECT 列表中的第1列排序
ORDER BY 编号按列名排序(等价)
ORDER BY 1 DESC按第1列降序排序

sql

-- 这三种写法等价(第1列是"编号")ORDER BY 1ORDER BY 编号ORDER BY (SELECT COUNT(order_id) FROM orderform A WHERE A.order_id >= B.order_id)


十、总结

问题答案
这段代码做什么?按 order_id 从大到小生成排名编号
编号顺序是什么?最终显示:从小到大(1,2,3,4)
为什么编号是从小到大?因为 ORDER BY 1 按编号列升序排序
子查询计算出的原始编号顺序?从大到小(4,3,2,1)
ORDER BY 1 什么意思?按 SELECT 列表的第1列升序排序
如何改为 order_id 从小到大排名?把 >= 改为 <=

一句话总结:这段代码通过相关子查询统计 A.order_id >= B.order_id 的记录数来计算编号——order_id 越大,满足条件的记录越少,计算出的编号越小(4,3,2,1);再通过 ORDER BY 1 按编号升序排序,最终显示为编号从小到大(1,2,3,4),对应 order_id 从大到小(4,3,2,1),实现按 order_id 降序排名


标签: