将列中的相似(但不相同)数据合并为单行

时间:2014-12-16 17:19:02

标签: sql-server tsql pivot

我是SQL Server的初学者,我正在努力弄清楚如何更新我的查询以便正确显示我的数据。

我检查了Combine similar column data from two rows into one row并试图通过QueryID进行分组,但是当我需要按照文本末尾的数字和ID#。我还看了很多关于pivot / unpivot的帖子来执行多个支点但我很难应用它。

我目前的查询和样本结果如下。我想要看到的是QueryID以相同的数字结尾并且员工ID相等,日期/等级/原因都返回到同一行而不是3个单独的行。我很感激任何指导。

With DisciplineTable as
(
   Select HrEmployees.Number, 
     HrEmployees.FirstName + ' ' + HrEmployees.LastName as Name,    
     HrEmployeeQueries.QueryID, 
     HrEmployeeQueries.Query, 
     HrEmployeeQueries.Response
    From HrEmployeeQueries
    Left Join HrEmployees on HrEmployees.EmployeeID = HrEmployeeQueries.EmployeeID
    Where QueryID Like 'DIS%')
Select * 
From DisciplineTable
Pivot(Max(Response) for Query in ([DATE:],[LEVEL:],[REASON:])) as DisciplinaryAction
Where QueryID Like 'DIS%' 
Order by Name

我的结果看起来像这样:

+-----+----------+---------+----------+---------+-------------+
|  #  |   Name   | QueryID |  DATE:   | LEVEL:  |   REASON:   |
+-----+----------+---------+----------+---------+-------------+
| 123 | John Doe | Date2   | 10/16/14 | Null    | Null        |
| 123 | John Doe | Level2  | Null     | Serious | Null        |
| 123 | John Doe | Reason2 | Null     | Null    | Attendance  |
| 123 | John Doe | Date3   | 12/13/14 | Null    | Null        |
| 123 | John Doe | Level3  | Null     | Major   | Null        |
| 123 | John Doe | Reason3 | Null     | Null    | Performance |
+-----+----------+---------+----------+---------+-------------+

我试图让它们看起来像这样。 Action列应填充QueryID末尾的数值,该值可能为1-10。 QueryID开头的文字始终为DateReasonLevel

+-----+----------+--------+----------+---------+-------------+
|  #  |   Name   | Action |  DATE:   | LEVEL:  |   REASON:   |
+-----+----------+--------+----------+---------+-------------+
| 123 | John Doe |      2 | 10/16/14 | Serious | Attendance  |
| 123 | John Doe |      3 | 12/13/14 | Major   | Performance |
+-----+----------+--------+----------+---------+-------------+

2 个答案:

答案 0 :(得分:3)

一些解决此问题的建议。部分问题是您在QueryID列中有多个值,因此PIVOT函数会对生成不同行的每个值进行分组。

首先,要获取Action值,您需要删除QueryID列中的字母字符。考虑到您将获得1-10的值,您可以使用STUFF and PATINDEX来获得此值。注意:有几种方法可以执行此操作,包括使用replace等。获得Action值后,即可应用PIVOT。这是一个示例版本:

select Number, Name, Action, [DATE:],[LEVEL:],[REASON:]
from
(
  select number, name, reason, query,
    Action = stuff(QueryID, 1, patindex('%[0-9]%', QueryID)-1, '')
  from yourdata
) d
pivot
(
  max(reason)
  for query in ([DATE:],[LEVEL:],[REASON:])
) p;

SQL Fiddle with Demo。然后将其添加到当前查询中:

With DisciplineTable as
(
    Select 
        HrEmployees.Number, 
        HrEmployees.FirstName + ' ' + HrEmployees.LastName as Name, 
        Action = stuff(HrEmployeeQueries.QueryID, 1, patindex('%[0-9]%', HrEmployeeQueries.QueryID)-1, '') , 
        HrEmployeeQueries.Query, 
        HrEmployeeQueries.Response
    From HrEmployeeQueries
    Left Join HrEmployees on HrEmployees.EmployeeID = HrEmployeeQueries.EmployeeID
    Where QueryID Like 'DIS%'
)
Select Number, Name, Action, [DATE:],[LEVEL:],[REASON:]
From DisciplineTable
Pivot
(
    Max(Response) for Query in ([DATE:],[LEVEL:],[REASON:])
) as DisciplinaryAction
Order by Name

答案 1 :(得分:0)

只需使用Max aggregate

添加group by即可
WITH DisciplineTable
     AS (SELECT HrEmployees.Number,
                HrEmployees.FirstName + ' '
                + HrEmployees.LastName AS NAME,
                substring(HrEmployeeQueries.QueryID,patindex('%[0-9]%',HrEmployeeQueries.QueryID),LEN(HrEmployeeQueries.QueryID))QueryID,
                HrEmployeeQueries.Query,
                HrEmployeeQueries.Response
         FROM   HrEmployeeQueries
                LEFT JOIN HrEmployees
                       ON HrEmployees.EmployeeID = HrEmployeeQueries.EmployeeID
         WHERE  QueryID LIKE 'DIS%')
SELECT [#],
       [Name],
       [QueryID] Action,
       [DATE:],
       [LEVEL:],
       [REASON:]
FROM   DisciplineTable
       PIVOT(Max(Response)
            FOR Query IN ([DATE:],
                          [LEVEL:],
                          [REASON:])) AS DisciplinaryAction
ORDER  BY NAME