Foxtable(狐表)用户栏目专家坐堂 → 捉摸了半天,搞不定,请各位指导一条SQL语句。


  共有14995人关注过本帖树形打印复制链接

主题:捉摸了半天,搞不定,请各位指导一条SQL语句。

帅哥哟,离线,有人找我吗?
狐狸爸爸
  1楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:管理员 帖子:47448 积分:251054 威望:0 精华:91 注册:2008/6/17 17:14:00
捉摸了半天,搞不定,请各位指导一条SQL语句。  发帖心情 Post By:2009/12/1 13:24:00 [只看该作者]

某列的值为:
1.1
1.2
1.2
1.3
1.4
...
2.1
2.5
....

希望用一条SQL 语句,按顺序替换为:
1
2
3
4
...

注意原始值有重复,也有间断,但替换的值不能重复或间断,必须按顺序。

[此贴子已经被作者于2009-12-1 13:25:35编辑过]

 回到顶部
帅哥哟,离线,有人找我吗?
lxl
  2楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信 一级勋章
等级:MVP荣誉狐 帖子:858 积分:6071 威望:0 精华:19 注册:2008/9/1 9:13:00
  发帖心情 Post By:2009/12/1 13:57:00 [只看该作者]

select ROW_NUMBER() over (order by 排序列),*
from 表

 回到顶部
帅哥哟,离线,有人找我吗?
狐狸爸爸
  3楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:管理员 帖子:47448 积分:251054 威望:0 精华:91 注册:2008/6/17 17:14:00
  发帖心情 Post By:2009/12/1 15:05:00 [只看该作者]

呵呵,谢了。

不过我要用Update,更新到后台的

 回到顶部
帅哥哟,离线,有人找我吗?
lxl
  4楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信 一级勋章
等级:MVP荣誉狐 帖子:858 积分:6071 威望:0 精华:19 注册:2008/9/1 9:13:00
  发帖心情 Post By:2009/12/1 15:46:00 [只看该作者]

有主键列吗?如果有主键列的话就好办一点:
update 表名
set 更新列 = t.rn
from 表名,(select 主键列,ROW_NUMBER() over(order by 更新列) As rn from 表名) t
where 表名.主键列 = t.主键列


 回到顶部
帅哥哟,离线,有人找我吗?
狐狸爸爸
  5楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:管理员 帖子:47448 积分:251054 威望:0 精华:91 注册:2008/6/17 17:14:00
  发帖心情 Post By:2009/12/1 15:52:00 [只看该作者]

有主键,不过Access不支持Row_Number()。

 回到顶部
帅哥哟,离线,有人找我吗?
mr725
  6楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信 一级勋章
等级:MVP荣誉狐 帖子:5154 积分:31434 威望:0 精华:8 注册:2008/9/8 12:27:00
  发帖心情 Post By:2009/12/1 16:19:00 [只看该作者]

o , 看看大师和大侠过招~   图片点击可在新窗口打开查看

 回到顶部
帅哥哟,离线,有人找我吗?
wcs
  7楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:五尾狐 帖子:1034 积分:7402 威望:0 精华:0 注册:2008/8/31 22:52:00
  发帖心情 Post By:2009/12/1 17:39:00 [只看该作者]

看得似懂非懂啊!!!


 回到顶部
帅哥哟,离线,有人找我吗?
菜鸟foxtable
  8楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信 菜鸟中的老鸟
等级:七尾狐 帖子:1486 积分:10064 威望:0 精华:9 注册:2008/11/14 8:54:00
  发帖心情 Post By:2009/12/1 18:00:00 [只看该作者]

看看这个有没有帮助?

一、树型关系的数据表

  不少程序员在进行数据库设计的时候都遇到过树型关系的数据,例如常见的类别表,即一个大类,下面有若干个子类,某些子类又有子类这样的情况。当类别不确定,用户希望可以在任意类别下添加新的子类,或者删除某个类别和其下的所有子类,而且预计以后其数量会逐步增长,此时我们就会考虑用一个数据表来保存这些数据。按照教科书上的教导,第二类程序员大概会设计出类似这样的数据表结构:


类别表_1(Type_table_1)

名称

类型

约束条件

说明

type_id

int

无重复

类别标识,主键

type_name

char(50)

不允许为空

类型名称,不允许重复

type_father

int

不允许为空

该类别的父类别标识,如果是顶节点的话设定为某个唯一值


  这样的设计短小精悍,完全满足3NF,而且可以满足用户的所有要求。是不是这样就行呢?答案是NO!Why?


  我们来估计一下用户希望如何罗列出这个表的数据的。对用户而言,他当然期望按他所设定的层次关系一次罗列出所有的类别,例如这样:

总类别

  类别1

    类别1.1

      类别1.1.1

    类别1.2

  类别2

    类别2.1

  类别3

    类别3.1

    类别3.2

  ……


  看看为了实现这样的列表显示(树的先序遍历),要对上面的表进行多少次检索?注意,尽管类别1.1.1可能是在类别3.2之后添加的记录,答案仍然是N次。这样的效率对于少量的数据没什么影响,但是日后类型扩充到数十条甚至上百条记录后,单单列一次类型就要检索数十次该表,整个程序的运行效率就不敢恭维了。或许第二类程序员会说,那我再建一个临时数组或临时表,专门保存类型表的先序遍历结果,这样只在第一次运行时检索数十次,再次罗列所有的类型关系时就直接读那个临时数组或临时表就行了。其实,用不着再去分配一块新的内存来保存这些数据,只要对数据表进行一定的扩充,再对添加类型的数量进行一下约束就行了,要完成上面的列表只需一次检索就行了。下面是扩充后的数据表结构:





类别表_2(Type_table_2)

名称

类型

约束条件

说明

type_id

int

无重复

类别标识,主键

type_name

char(50)

不允许为空

类型名称,不允许重复

type_father

int

不允许为空

该类别的父类别标识,如果是顶节点的话设定为某个唯一值

type_layer

char(6)

限定3层,初始值为000000

类别的先序遍历,主要为减少检索数据库的次数


  按照这样的表结构,我们来看看上面例子记录在表中的数据是怎样的:


type_id

type_name

type_father

type_layer

1

总类别

0

000000

2

类别1

1

010000

3

类别1.1

2

010100

4

类别1.2

2

010200

5

类别2

1

020000

6

类别2.1

5

020100

7

类别3

1

030000

8

类别3.1

7

030100

9

类别3.2

7

030200

10

类别1.1.1

3

010101

……


  现在按type_layer的大小来检索一下:SELECT * FROM Type_table_2 ORDER BY type_layer


列出记录集如下:


type_id

type_name

type_father

type_layer

1

总类别

0

000000

2

类别1

1

010000

3

类别1.1

2

010100

10

类别1.1.1

3

010101

4

类别1.2

2

010200

5

类别2

1

020000

6

类别2.1

5

020100

7

类别3

1

030000

8

类别3.1

7

030100

9

类别3.2

7

030200

……


  现在列出的记录顺序正好是先序遍历的结果。在控制显示类别的层次时,只要对type_layer字段中的数值进行判断,每2位一组,如大于0则向右移2个空格。当然,我这个例子中设定的限制条件是最多3层,每层最多可设99个子类别,只要按用户的需求情况修改一下type_layer的长度和位数,即可更改限制层数和子类别数。其实,上面的设计不单单只在类别表中用到,网上某些可按树型列表显示的论坛程序大多采用类似的设计。


  或许有人认为,Type_table_2中的type_father字段是冗余数据,可以除去。如果这样,在插入、删除某个类别的时候,就得对type_layer 的内容进行比较繁琐的判定,所以我并没有消去type_father字段,这也正符合数据库设计中适当保留冗余数据的来降低程序复杂度的原则,后面我会举一个故意增加数据冗余的案例。


 回到顶部
帅哥哟,离线,有人找我吗?
lxl
  9楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信 一级勋章
等级:MVP荣誉狐 帖子:858 积分:6071 威望:0 精华:19 注册:2008/9/1 9:13:00
  发帖心情 Post By:2009/12/1 20:23:00 [只看该作者]

我没办法了图片点击可在新窗口打开查看

access 里面实现row_number是这样的:
假设有成绩表:

表a
name score
A 54
B 21
C 12
D 25
E 41
F 25
G 13
H 71
I 8
J 66
K 72
L 5
M 56
N 29
O 85
P 23
Q 67
R 74
S 41
T 23
U 74
V 19

SELECT a.name, (Sum(IIf(b.score<a.score,1,0))+Sum(IIf(b.score=a.score And b.name<=a.name,1,0))) AS row_number
FROM a, a AS b
group by a.name


但是update a,r set a.score = r.row_number where a.name=r.name
这里老实提示操作必须是可更新的查询,不明白为什么。
只是想根据排好的序更新a表,可系统会要求r表必须是可更新的

[此贴子已经被作者于2009-12-1 20:25:38编辑过]

 回到顶部
帅哥哟,离线,有人找我吗?
lxl
  10楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信 一级勋章
等级:MVP荣誉狐 帖子:858 积分:6071 威望:0 精华:19 注册:2008/9/1 9:13:00
  发帖心情 Post By:2009/12/1 22:31:00 [只看该作者]

有一个替代办法:
在Access查询的 SQL视图里面分别输入下面3个sql:
SELECT a.name, (Sum(IIf(b.score<a.score,1,0))+Sum(IIf(b.score=a.score And b.name<=a.name,1,0))) AS row_number into r
FROM a, a AS b
group by a.name;
点感叹号执行后输入:
update a,r set a.score = r.row_number where a.name=r.name
点感叹号执行后输入:
drop table r


 回到顶部
总数 12 1 2 下一页