在访问数据库中等效的dense_rank()函数

时间:2011-09-14 20:06:33

标签: sql ms-access

因为我们在sql server中有dense_rank函数,所以我们在访问中是否有任何等价物?

我有一张桌子

employee_name employee_address
RON           23-B, TORONTO
PETER         15-C, NY
TED           23-C, LONDON
RON           23-B, TORONTO

我必须在此表中添加新列,如下所示:

employee_name employee_address   employee_no
RON           23-B, TORONTO      1
PETER         15-C, NY           2
TED           23-C, LONDON       3
RON           23-B, TORONTO      1

1 个答案:

答案 0 :(得分:1)

  • 我假设您希望在访问SQL Server查询中 port ,如下所示:

SELECT * ,DENSE_RANK() OVER(ORDER BY employee_name, employee_address) AS DenseRank FROM Employee

  • 主要思想是生成一个具有不同employee_name & employee_address值的列表,然后我们为每个不同的元组生成没有间隙的行号。在最后一步,我们在初始数据集(Employee表)和最后一个数据集(每个不同的employee_name & employee_address元组的行号)之间建立一个JOIN。

解决方案1 ​​

Query0

CREATE TABLE Employee ( employee_id INT PRIMARY KEY ,employee_name VARCHAR(100) NOT NULL ,employee_address VARCHAR(100) NOT NULL );

查询1

INSERT INTO Employee (employee_id, employee_name, employee_address) VALUES (1,'RON','23-B, TORONTO');

QUERY2

INSERT INTO Employee (employee_id, employee_name, employee_address) VALUES (2,'PETER','15-C, NY');

QUERY3

INSERT INTO Employee (employee_id, employee_name, employee_address) VALUES (3,'TED','23-C, LONDON');

Query4

INSERT INTO Employee (employee_id, employee_name, employee_address) VALUES (4,'SORIN','09-S, VASCAUTI');

QUERY5

INSERT INTO Employee (employee_id, employee_name, employee_address) VALUES (5,'RON','23-B, TORONTO');

Query6

INSERT INTO Employee (employee_id, employee_name, employee_address) VALUES (6,'PETER','15-C, NY');

Query7

INSERT INTO Employee (employee_id, employee_name, employee_address) VALUES (7,'SORIN','09-S, VASCAUTI');

Query8

INSERT INTO Employee (employee_id, employee_name, employee_address) VALUES (8,'PETER','15-C, NY');

因此,员工的内容将是:

employee_id employee_name                                                                                        employee_address
----------- ---------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------
1           RON                                                                                                  23-B, TORONTO
2           PETER                                                                                                15-C, NY
3           TED                                                                                                  23-C, LONDON
4           SORIN                                                                                                09-S, VASCAUTI
5           RON                                                                                                  23-B, TORONTO
6           PETER                                                                                                15-C, NY
7           SORIN                                                                                                09-S, VASCAUTI
8           PETER                                                                                                15-C, NY

Query9 我们为每个employee_name & employee_address元组生成行号

CREATE TABLE TmpEmployee
(
    rownumber COUNTER(1,1) PRIMARY KEY
    ,employee_name VARCHAR(100) NOT NULL
    ,employee_address VARCHAR(100) NOT NULL
);

COUNTER(1,1)是Access / SQL AutoNumber数据类型;在每次执行Query10之前,您需要重新创建TmpEmployee表,或者需要压缩Access DB以将rownumber计数器重置为1)和

Query10

INSERT INTO TmpEmployee (employee_name, employee_address)
SELECT   e.employee_name, e.employee_address
        FROM     Employee e
        GROUP BY e.employee_name, e.employee_address

结果:

rownumber   employee_name                                                                                        employee_address
----------- ---------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------
1           PETER                                                                                                15-C, NY
2           RON                                                                                                  23-B, TORONTO
3           SORIN                                                                                                09-S, VASCAUTI
4           TED                                                                                                  23-C, LONDON

Query11 最终结果:

SELECT e.*, t.RowNumber AS DenseRank
FROM Employee e
INNER JOIN TmpEmployee t ON e.employee_name = t.employee_name AND e.employee_address = t.employee_address
ORDER BY e.employee_name, e.employee_address

结果:

2   PETER   15-C, NY    1
6   PETER   15-C, NY    1
8   PETER   15-C, NY    1
5   RON 23-B, TORONTO   2
1   RON 23-B, TORONTO   2
4   SORIN   09-S, VASCAUTI  3
7   SORIN   09-S, VASCAUTI  3
3   TED 23-C, LONDON    4

解决方案2 Query9 最终结果:

SELECT   e.*, c.RowNumber
FROM     Employee e INNER JOIN
(
SELECT  a.employee_name, a.employee_address, COUNT(b.employee_name) AS RowNumber
        FROM
    (
        SELECT   e.employee_name, e.employee_address
        FROM     Employee e
        GROUP BY e.employee_name, e.employee_address
    ) a,
    (
        SELECT  e.employee_name, e.employee_address
        FROM     Employee e
        GROUP BY e.employee_name, e.employee_address
    ) b 
WHERE a.employee_name > b.employee_name  OR a.employee_name = b.employee_name AND a.employee_address >= b.employee_address 
    GROUP BY a.employee_name, a.employee_address
) c ON e.employee_name = c.employee_name AND e.employee_address = c.employee_address
ORDER BY c.employee_name, c.employee_address