使用select查询对大写和小写的相同值进行分组

时间:2017-06-16 11:25:00

标签: sql sql-server sql-server-2008

在下表中 InputParameterName 列包含 Product1 P 大写)和 pRoduct1 R 大写)。

表1:

InputParameterName  Period  PeriodInput
Product1             2017   25704
Product1             2018   25704
pRoduct1             2017   16
pRoduct1             2018   16
pRoduct1             2017   57.6
pRoduct1             2018   57.6
pRoduct1             2017   40.5
pRoduct1             2018   40.5

我的查询:

SELECT InputParameterName, Period, SUM(CAST(PeriodInput AS FLOAT)) PeriodInput  
FROM Table1         
GROUP BY InputParameterName, Period

结果:

InputParameterName  Period  PeriodInput
Product1                    2017    25818.1
pRoduct1                    2018    25818.1

在结果中,您可以看到InputParameterName列包含 Product1 P 大写)和 pRoduct1 R 大写)。

有没有办法让两者都相同, Product1 pRoduct1 (没有应用任何字符大小写转换的确切值)?

3 个答案:

答案 0 :(得分:2)

使用lower()upper()

SELECT MIN(InputParameterName) as InputParameterName, Period,
       SUM(CAST(PeriodInput AS FLOAT)) PeriodInput  
FROM Table1         
GROUP BY LOWER(InputParameterName), Period;

LOWER()中的使用GROUP BY定义。它未在SELECT中使用,因此您始终可以在数据中获取值。

如果您不关心这种情况,那么您应该考虑设置列,表或数据库的collation,以便在涉及字符串的表达式中忽略大小写。

编辑:

如果上面的结果返回两行,那么大小写不是问题。你可能有隐藏的角色。最有可能是空格,所以你可以尝试:

GROUP BY LOWER(REPLACE(InputParameterName, ' ', '')), Period;

希望隐藏的空间不比空间复杂。

编辑II:

我现在明白了。你想要两行,你只想要值相同。然后窗口函数可以做你想要的:

SELECT MIN(InputParameterName) OVER (PARTITION BY LOWER(InputParameterName)),
       Period, SUM(CAST(PeriodInput AS FLOAT)) as PeriodInput  
FROM Table1         
GROUP BY InputParameterName, Period;

答案 1 :(得分:1)

使用LOWER()

SELECT
    LOWER(InputParameterName) AS InputParameterName,
    Period,
    SUM(CAST(PeriodInput AS FLOAT)) PeriodInput  
FROM Table1         
GROUP BY
    LOWER(InputParameterName),
    Period

要严格遵守ANSI,我们不应在GROUP BY子句中使用列的函数。在这种情况下,我们可以使用派生表:

WITH cte AS (
    SELECT
        LOWER(InputParameterName) AS InputParameterName,
        Period,
        PeriodInput
    FROM Table1
)
SELECT
    InputParameterName,
    Period,
    SUM(CAST(PeriodInput AS FLOAT)) PeriodInput  
FROM cte       
GROUP BY
    InputParameterName,
    Period

答案 2 :(得分:1)

通过使用Row_Number()和对“期间”列进行分区,您可以获得所需的结果

;With cte(InputParameterName,Period,PeriodInput)
    AS
    (
    SELECT 'Product1', 2017,25704 Union all
    SELECT 'Product1', 2018,25704 Union all
    SELECT 'product1', 2017,16    Union all
    SELECT 'product1', 2018,16    Union all
    SELECT 'product1', 2017,57.6  Union all
    SELECT 'product1', 2018,57.6  Union all
    SELECT 'product1', 2017,40.5  Union all
    SELECT 'product1', 2018,40.5
    )
    SELECT InputParameterName,Period,PeriodInput FRom
    (
    SELECT  InputParameterName,
            Period,
            CAST(SUM(PeriodInput)OVER(Partition by Period Order BY Period) AS FLOAT)AS PeriodInput,
            ROW_NUMBER()OVER(Partition by Period Order BY Period)AS Seq From cte    
    )DT
    WHERE DT.Seq=1

输出

InputParameterName  Period  PeriodInput
--------------------------------------
product1            2017    25818.1
product1            2018    25818.1