想象一下,我有一个像这样的非规范化表:
CREATE TABLE Persons
(
Id int identity primary key,
FirstName nvarchar(100),
CountryName nvarchar(100)
)
INSERT INTO Persons
VALUES ('Mark', 'Germany'),
('Chris', 'France'),
('Grace', 'Italy'),
('Antonio', 'Italy'),
('Francis', 'France'),
('Amanda', 'Italy');
我需要构建一个查询来返回每个人的姓名,以及他们所在国家/地区的唯一 ID。ID 不一定必须是连续的;更重要的是,它们不必按任何顺序排列。实现这一目标的最有效方法是什么?
最简单的解决方案似乎是DENSE_RANK
:
SELECT FirstName,
CountryName,
DENSE_RANK() OVER (ORDER BY CountryName) AS CountryId
FROM Persons
-- FirstName CountryName CountryId
-- Chris France 1
-- Francis France 1
-- Mark Germany 2
-- Amanda Italy 3
-- Grace Italy 3
-- Antonio Italy 3
但是,这会在我的CountryName
专栏中引起排序,这是一种浪费的性能猪。我想出了这个替代方案,它使用ROW_NUMBER
众所周知的技巧来抑制其排序:
SELECT P.FirstName,
P.CountryName,
C.CountryId
FROM Persons P
JOIN (
SELECT CountryName,
ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS CountryId
FROM Persons
GROUP BY CountryName
) C
ON C.CountryName = P.CountryName
-- FirstName CountryName CountryId
-- Mark Germany 2
-- Chris France 1
-- Grace Italy 3
-- Antonio Italy 3
-- Francis France 1
-- Amanda Italy 3
我是否正确假设第二个查询通常会更好地执行(不仅仅是在我设计的数据集上)?是否有任何可能产生影响的因素(例如 上的索引CountryName
)?有没有更优雅的表达方式?