راهکار جامع DISTINCT در SQL Server: مدیریت حساسیت حروف (Case-Insensitive)
این مقاله به یک مشکل رایج در هنگام استفاده از DISTINCT در دیتابیسهای SQL Server که به حروف کوچک و بزرگ حساس نیستند، میپردازد. زمانی که شما مقادیر متمایز (Distinct) را از یک ستون انتخاب میکنید، اما همچنان مقادیری را دریافت میکنید که تنها تفاوت آنها در حالت حروف (بزرگ یا کوچک بودن) است.
ابتدا یک جدول نمونه ایجاد کرده و تعدادی داده برای نمایش این مشکل وارد میکنیم.
CREATE TABLE MyTest
(
MyId INT IDENTITY(1,1),
MyName VARCHAR(100)
)
GO
INSERT INTO MyTest (MyName) VALUES ('TEST')
INSERT INTO MyTest (MyName) VALUES ('test')
INSERT INTO MyTest (MyName) VALUES ('Test')
INSERT INTO MyTest (MyName) VALUES ('tEst')
INSERT INTO MyTest (MyName) VALUES ('TEST')
INSERT INTO MyTest (MyName) VALUES ('anotherTest')
INSERT INTO MyTest (MyName) VALUES ('anotherTest')
GO
حالا بیایید مقادیر متمایز را از ستون MyName انتخاب کنیم و نتیجه را ببینیم.
SELECT DISTINCT MyName
FROM MyTest
همانطور که مشاهده میکنید، ما همچنان چندین سطر دریافت میکنیم، با اینکه دادهها یکسان هستند و تنها تفاوت در حالت حروف است. این اتفاق میافتد زیرا دیتابیس به حروف کوچک و بزرگ حساس نیست، بنابراین ‘TEST’ و ‘test’ مقادیر یکسانی در نظر گرفته میشوند، اما DISTINCT بر روی مقادیر خام (raw values) کار میکند.
برای غلبه بر این مشکل، میتوانیم از یک Collation (ترتیببندی) با حساسیت به حروف کوچک و بزرگ برای ستونی که انتخاب میکنیم، استفاده کنیم.
بنابراین، به جای انتخاب صرف `MyName`، میتوانیم `MyName` را با یک Collation خاص که به حروف کوچک و بزرگ حساس است، انتخاب کنیم، مانند:
(COLUMN_NAME COLLATE SQL_Latin1_General_CP1_CS_AS)
پسوند `_CS_AS` به معنای حساس به حروف کوچک و بزرگ (Case Sensitive) و حساس به لهجه (Accent Sensitive) است. حالا بیایید کوئری را مجدداً با Collation اجرا کنیم.
SELECT DISTINCT MyName COLLATE SQL_Latin1_General_CP1_CS_AS
FROM MyTest
اکنون مقادیر متمایزی را که انتظار داشتیم، دریافت میکنیم.
روش دیگر برای دستیابی به این هدف، استفاده از عبارت GROUP BY برای بدست آوردن مقادیر متمایز و اعمال Collation در بند GROUP BY است.
بنابراین، به جای صرفاً `GROUP BY MyName`، شما `GROUP BY MyName` را با یک Collation خاص و حساس به حروف کوچک و بزرگ، مانند:
(COLUMN_NAME COLLATE SQL_Latin1_General_CP1_CS_AS)
بیایید این را در عمل ببینیم.
SELECT MyName
FROM MyTest
GROUP BY MyName COLLATE SQL_Latin1_General_CP1_CS_AS
همانطور که مشاهده میکنید، این روش نیز نتایج مورد انتظار را ارائه میدهد.
برای پاکسازی جدول.
DROP TABLE MyTest
GO