本文介绍如何在执行 SELECT 语句时动态地对行排序。这是一种很灵活的方法,也可能是唯一可能的解决方法。 它比过程解决方法更快一些。行编号或排序是一个典型的过程问题。其解决方法通常是基于循环函数和临时表,即 SQL Server 循环函数和游标函数。此技术基于自动联接技术。所选的关系一般为“大于”。其目的是当集合与本身比较时,统计特定数据集合的每个元素有多少次实现了“大于”关系。
注意:以下示例均基于 pubs 数据库。
示例 1
在此示例中:
Set 1 是作者。
Set 2 是作者。
关系是“姓名大于”。
通过将“名 + 姓”与其他的“名 + 姓”进行比较,可以避免重复问题。
用 count(*) 统计关系实现的次数。
查询:
select rank=count(*), a1.au_lname, a1.au_fname
from authors a1, authors a2
where a1.au_lname + a1.au_fname >= a2.au_lname + a2.au_fname
group by a1.au_lname, a1.au_fname
order by 1
结果:
Rank Au_Lname Au_Fname
---- -------------- -----------
1 Bennet Abraham
2 Blotchet-Halls Reginald
3 Carson Cheryl
4 DeFrance Michel
5 del Castillo Innes
6 Dull Ann
7 Greene Morningstar
8 Green Marjorie
9 Gringlesby Burt
10 Hunter Sheryl
11 Karsen Livia
12 Locksley Charlene
13 MacFeather Stearns
14 McBadden Heather
15 O'Leary Michael
16 Panteley Sylvia
17 Ringer Albert
18 Ringer Anne
19 Smith Meander
20 Straight Dean
21 Stringer Dirk
22 White Johnson
23 Yokomoto Akiko
(23 row(s) affected)
示例 2
在此示例中:
按书店售出的书籍数对书店排序。
Set 1 是书店售出的书籍数:select stor_id, qty=sum(qty) from sales group by stor_id.
Set 2 是书店售出的书籍数:select stor_id, qty=sum(qty) from sales group by stor_id.
关系是“书籍数大于”。
为避免重复,在该示例中您可以比较 price*qty 而不是 qty。
查询:
select rank=count(*), s1.stor_id, qty=sum(s1.qty)
from (select stor_id, qty=sum(qty) from sales group by stor_id) s1,
(select stor_id, qty=sum(qty) from sales group by stor_id) s2
where s1.qty >= s2.qty
group by s1.stor_id
order by 1
以下某些示例只能在 Microsoft SQL Server 6.5 中运行,因为它们在 FROM 子句中使用了派生表。
示例 3
在此示例中:
按收入将出版者排序。
Set 1 是出版者的全部销售额:
select t.pub_id, sales=sum(s.qty*t.price)
from sales s, titles t
where s.title_id=t.title_id
and t.price is not null
group by t.pub_id
Set 2 是出版者的全部销售额:
select t.pub_id, sales=sum(s.qty*t.price)
from sales s, titles t
where s.title_id=t.title_id
and t.price is not null
group by t.pub_id
关系是“收入大于”。
查询:
select rank=count(*), s1.pub_id, sales=sum(s1.sales)
from (select t.pub_id, sales=sum(s.qty*t.price)
from sales s, titles t
where s.title_id=t.title_id
and t.price is not null
group by t.pub_id) s1,
(select t.pub_id, sales=sum(s.qty*t.price)
from sales s, titles t
where s.title_id=t.title_id
and t.price is not null
group by t.pub_id) s2
where s1.sales>= s2.sales
group by s1.pub_id
order by 1
select rank=count(*), s1.title_id, qty=sum(s1.qty)
from (select title_id, qty=sum(qty) from sales group by title_id) s1,
(select title_id, qty=sum(qty) from sales group by title_id) s2
where s1.qty >= s2.qty
group by s1.title_id
order by 1
CREATE VIEW v_pub_rank
AS
select rank=count(*), s1.title_id, qty=sum(s1.qty)
from (select title_id, qty=sum(qty) from sales group by title_id) s1,
(select title_id, qty=sum(qty) from sales group by title_id) s2
where s1.qty >= s2.qty
group by s1.title_id
CREATE VIEW v_title_rank
AS
select rank=count(*), s1.title_id, qty=sum(s1.qty)
from (select title_id, qty=sum(qty) from sales group by title_id) s1,
(select title_id, qty=sum(qty) from sales group by title_id) s2
where s1.qty >= s2.qty
group by s1.title_id
查询:
select Book=convert(varchar(45),replicate (' ', 2*rank) +
title_id +
replicate(' ', 35-2*rank)+': '),
qty
from v_title_rank
order by rank