mssql合并具有相似值的行

时间:2018-07-12 06:58:40

标签: sql sql-server case-when

我有以下观点:

item_name    2018-1    2018-2   2018-3
windows      null      34       null
windows_old  3         3        44
linux        23        2        null
linux CR     null      null     45

我想使用正则表达式将名称相似的行合并为一个(以及对行中的数字求和)(例如,将item_name匹配“ ^ windows”的所有内容合并)

因此最终结果将是:

item_name    2018-1    2018-2   2018-3
windows      3         37       44
linux        23        2        45

3 个答案:

答案 0 :(得分:1)

您可以尝试使用CASE WHENSUM函数。编写一个子查询来设置相似的名称。

测试DDL

CREATE TABLE T(
  item_name VARCHAR(50),
  Col1 INT,
  Col2 INT,
  Col3 INT
);

INSERT INTO T VALUES ('windows',null,34,null);
INSERT INTO T VALUES ('windows_old',3,3,44);
INSERT INTO T VALUES ('linux',23,2,null);
INSERT INTO T VALUES ('linux CR',null ,null,45);

查询:

SELECT 
    new_name as 'item_name',
    SUM(CASE WHEN item_name LIKE '%'+item_name+'%' THEN Col1 END),
    SUM(CASE WHEN item_name LIKE '%'+item_name+'%' THEN Col2 END),
    SUM(CASE WHEN item_name LIKE '%'+item_name+'%' THEN Col3 END)
FROM (SELECT *,
      coalesce(
            (CASE WHEN item_name LIKE '%windows%' THEN 'windows' END),
            (CASE WHEN item_name LIKE '%linux%' THEN 'linux' END)
       ) new_name 
      FROM T
) t
GROUP BY new_name 

结果

| new_name | 2018-1 | 2018-2 | 2018-3 |
|----------|--------|--------|--------|
|    linux |     23 |      2 |     45 |
|  windows |      3 |     37 |     44 |

sqlfiddle

答案 1 :(得分:0)

如果没有其他信息,我建议您使用UNION(全部):

SELECT 'windows' AS [Bezeichnung]
    , COUNT/SUM(...) AS [n]
FROM [Object(s)]
WHERE [item_name] LIKE 'windows%'

UNION ALL

SELECT 'linux' AS [Bezeichnung]
    , COUNT/SUM(...) AS [n]
FROM [Object(s)]
WHERE [item_name] LIKE 'linux%'

答案 2 :(得分:0)

尝试使用正则表达式/ patIndex

SELECT 
        Case patIndex ('%[ _/-]%', LTrim (item_name))
            When 0 Then LTrim (item_name)
            Else substring (LTrim (item_name), 1, patIndex ('%[ _/-]%', LTrim (item_name)) - 1)
        End item,
        SUM([2018-1]) as [2018-1],
        SUM([2018-2]) as [2018-2],
        SUM([2018-3]) as [2018-3]
    FROM T
    GROUP BY Case patIndex ('%[ _/-]%', LTrim (item_name))
            When 0 Then LTrim (item_name)
            Else substring (LTrim (item_name), 1, patIndex ('%[ _/-]%', LTrim (item_name)) - 1)
            END

sqlFiddle