如何规范分组列的大小写?

时间:2016-09-22 11:09:37

标签: sql sql-server group-by case-sensitive case-insensitive

在配置为不区分大小写的SQL Server上,me@ubuntu:~/openssl-1.1.0$ openssl aes-256-cbc -a -d -in file.txt.enc -out file.txt.dec2 enter aes-256-cbc decryption password: 123 bad decrypt 140456117421728:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:evp_enc.c:539: 列不是第一个group by列时,[n][var]char可能会产生有趣的结果。从本质上讲,它看起来像它遇到的任何行"首先" (其中"首先"在没有订单的情况下未定义):为该分组获胜。例如:

group by
对我来说,

返回:

select x.[day], x.[name], count(1) as [count]
from (
    select 1 as [day], 'a' as [name]
    union all select 1, 'A'
    union all select 2, 'A'
    union all select 2, 'a'
    ) x group by x.[day], x.[name]

使用day name count ----------- ---- ----------- 1 A 2 2 a 2 无效,因为分组已经发生。

我无法在min(x.[name]) 之前添加order by ,因为这是非法的;在之后添加group by order by只是在分组后定义输出顺序 - 它仍然会提供group bya

那么:有没有一种理智的方式来做到这一点,资本化至少对所有分组都是一致的? (我将在另一天离开,为单独的运行保持一致的问题)

所需的输出:

A

或:

day         name count
----------- ---- -----------
1           A    2
2           A    2

编辑:没有在群组之间保持一致时销毁大小写。所以没有上/下。因此,如果其中一个组始终具有值day name count ----------- ---- ----------- 1 a 2 2 a 2 ,我希望该行的结果为BcDeF,而不是BcDeFbcdef

4 个答案:

答案 0 :(得分:9)

我会使用窗口函数。通过使用System.out.println(date); 并使用不区分大小写的排序分区,但按区分大小写排序,我们将始终选择一个带有原始大小写的结果,但它会将它们分组,就好像它们是相同的一样:

ROW_NUMBER

它返回:

WITH CTE AS
(
    SELECT  *,
            RN = ROW_NUMBER() OVER(PARTITION BY [day], [name]
                                   ORDER BY [name] COLLATE SQL_Latin1_General_Cp1_Cs_AS),
            N = COUNT(*) OVER(PARTITION BY [day], [name])
    FROM (  select 1 as [day], 'a' as [name]
            union all select 1, 'A'
            union all select 2, 'A'
            union all select 2, 'a'
            union all select 3, 'BcDeF'
            union all select 3, 'bCdEf') X
)
SELECT *
FROM CTE
WHERE RN = 1;

按照@ AndriyM的评论,如果你想在整个结果集上使用相同的大小写,而不是在同一天,你可以使用:

╔═════╦═══════╦════╦═══╗
║ day ║ name  ║ RN ║ N ║
╠═════╬═══════╬════╬═══╣
║   1 ║ A     ║  1 ║ 2 ║
║   2 ║ A     ║  1 ║ 2 ║
║   3 ║ BcDeF ║  1 ║ 2 ║
╚═════╩═══════╩════╩═══╝

答案 1 :(得分:2)

使用upper()lower()

select x.[day], lower(x.[name]) as name, count(1) as [count]
from (
    select 1 as [day], 'a' as [name]
    union all select 1, 'A'
    union all select 2, 'A'
    union all select 2, 'a'
    ) x
group by x.[day], x.[name];

SQL Server从不确定的行中选择一个值是正确的。 min()max()没有帮助,因为价值相同。最简单的解决方案是明确选择您想要的案例。

答案 2 :(得分:2)

Group by中使用不区分大小写的排序规则,例如:

select day, name, count(*)
from tablename
group by day, name collate SQL_Latin1_General_Cp1_CI_AS_KI_WI

也许SQL Server在这里有问题?使用另一个dbms,它执行:

SQL>create table t (d int, name varchar(10));
SQL>insert into t values (1,'A');
SQL>insert into t values (2,'A');
SQL>insert into t values (2,'a');
SQL>insert into t values (3,'BcDeF');
SQL>insert into t values (3,'bCdEf');
SQL>insert into t values (4,'a');
SQL>select d, name, count(*)
SQL&from t
SQL&group by d, name collate english_1;
          d name
=========== ========== ====================
          1 A                             1
          2 A                             2
          3 BcDeF                         2
          4 a                             1

                  4 rows found

其中english_1是不区分大小写的排序规则。

正如预期的那样?

答案 3 :(得分:0)

您可以在UPPER子句中使用GROUP BY将所有值转移到相同的大小写。