Сделать запрос GroupBy чувствительным к регистру - PullRequest
0 голосов
/ 24 января 2019

У меня есть таблица, и у нее есть некоторые данные

Table User

Я пытаюсь написать запрос GroupBy как этот

SELECT  [name] FROM [Example].[dbo].[User] Group By [Example].[dbo].[User].[name]

Но он показывает только одну запись Group By query

Мне нужно получить все три записи, потому что они разделены регистром.Как написать запрос GroupBy с учетом регистра?

Ответы [ 4 ]

0 голосов
/ 24 января 2019

Пара решений здесь, в зависимости от вашей цели.Если вам очень нужна чувствительная к регистру версия, но вы не хотите изменять параметры сортировки базы данных / столбца, я рекомендую вычисляемый столбец:

USE Sandbox;
GO
--Alter the whole database
--ALTER DATABASE [Sandbox] COLLATE Latin1_General_CS_AI; --Commented out as unlikely to be the answer

CREATE TABLE dbo.[User] --I suggest a different name, USER is a reserved word in T-SQL
    (id int,
     [name] varchar(20)); --Name isn't reserved, but is a keyord, so you probably want to use a different name a again

INSERT INTO dbo.[User] ([id],
                        [name])
VALUES(1,'abc'),
      (1,'Abc'),
      (1,'ABC');
GO

--Current example
SELECT [name]
FROM dbo.[User]
GROUP BY [name];

--use COLLATE

SELECT [name] COLLATE Latin1_General_CS_AI AS [name]
FROM dbo.[User]
GROUP BY [name] COLLATE Latin1_General_CS_AI;
GO

--Alter the column's collation
--ALTER TABLE dbo.[User] ALTER [name] varchar(20) COLLATE Latin1_General_CS_AI; --Probably not the right solution either.

--Add a Collated calculated column    
ALTER TABLE dbo.[User] ADD name_CS AS [name] COLLATE Latin1_General_CS_AI PERSISTED;
GO

SELECT [name_CS] AS [name]
FROM dbo.[User]
GROUP BY [name_CS];
GO
--Cleanup
DROP TABLE dbo.[User];
0 голосов
/ 24 января 2019

Вам нужно изменить параметры сортировки столбца на тот, который чувствителен к регистру.Например:

SELECT [name] COLLATE Latin1_General_100_CS_AS_SC;
       FROM [Example].[dbo].[User]
       GROUP BY [Example].[dbo].[User].[name] COLLATE Latin1_General_100_CS_AS_SC;

Чувствительные к регистру параметры сортировки обычно имеют CS в названии.

Чтобы выбрать, какое сравнение использовать, вы можете найти объединение столбца с помощью:

SELECT c.collation_name
       FROM sys.columns c
            INNER JOIN sys.objects o
                       ON o.object_id = c.object_id
                          AND o.type = 'U'
            INNER JOIN sys.schemas s
                       ON s.schema_id = o.schema_id
       WHERE lower(s.name) = 'dbo'
             AND lower(o.name) = 'user'
             AND lower(c.name) = 'name';

Хорошее предположение состоит в том, чтобы взять это сопоставление и заменить CI (без учета регистра) на CS и использовать его, как показано выше.

0 голосов
/ 24 января 2019
ALTER TABLE dbo.User
ALTER COLUMN name VARCHAR(50) COLLATE Latin1_General_CS_AS NOT NULL;

Тогда ваш код запроса может остаться таким же, как сейчас.

0 голосов
/ 24 января 2019

Это сортировка.CS означает регистр, а CI - регистр.

Я покажу вам пример:

USE YourDb;

WITH CS AS 
(
    SELECT 'CaseSensitive' COLLATE SQL_Latin1_General_CP1_CS_AS AS ColA 
)

SELECT * FROM CS WHERE ColA = 'casesensitive';

WITH CI AS 
(
    SELECT 'CaseSensitive' COLLATE SQL_Latin1_General_CP1_CI_AS AS ColA 
)

SELECT * FROM CI WHERE ColA = 'casesensitive'
...