次のような非正規化テーブルがあるとします。
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
2 番目のクエリが一般的に (私の不自然なデータ セットだけでなく) パフォーマンスが向上すると仮定するのは正しいですか? どちらの方法でも違いを生む可能性のある要因はありますか (のインデックスなどCountryName
)? よりエレガントな表現方法はありますか?