【问题标题】:Combine similar (but not same) data from column into single row将列中相似(但不相同)的数据组合成单行
【发布时间】:2015-02-15 02:20:56
【问题描述】:

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

我查看了Combine similar column data from two rows into one row 并尝试在 QueryID 上进行分组,但是当我需要它按文本末尾的数字和 id# 分组时,我不确定如何应用它。我还查看了许多关于枢轴/取消枢轴以执行多个枢轴的帖子,但我正在努力应用它。

我当前的查询和示例结果如下。我想看到的是 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 |
+-----+----------+--------+----------+---------+-------------+

【问题讨论】:

  • CTE内部查询的输出是什么
  • 什么是Action?看起来您需要从子查询中删除 QueryID 列并将其替换为 Action 列。
  • @bluefeet Action 只是 QueryID 末尾的数字 - 所以 Date2、Level2 和 Reason 2 将在 Action 列中显示为 2。
  • @HRIS 操作是否只有一个数值,例如23?或者你会有10100
  • @NoDisplayName - 枢轴之前的 DisciplineTable 结果基本上是这样的:123 |约翰·多伊 |日期2 |日期:| 2014 年 10 月 16 日,因此枢轴将 DATE、LEVEL 和 REASON 作为列标题向上移动到其“响应”之上。

标签: sql-server tsql pivot


【解决方案1】:

一些解决此问题的建议。部分问题是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

【讨论】:

    【解决方案2】:

    只需添加Max aggregategroup 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 
    

    【讨论】:

    • 不是我的 DV,而是一些 cmets - 首先,您可能不需要外部查询中的 WHERE - 应该在内部查询中过滤所有内容。其次,为什么不在内部查询中修剪QueryID,这样您就不必两次应用聚合函数?第三,他们表示QueryID 最多可以达到 10 个,因此无法获取最后一个字符。
    • @bluefeet - 是的,我没有在外部查询中看到 where 子句!感谢指出错误
    • @NoDisplayName 该查询在更新之前工作以处理 queryid(可能为 2 位),唯一的问题是 10 显示为 0。更新后,我收到以下错误:Msg 102,级别 15,状态 1,第 6 行 'HrEmployeeQueries' 附近的语法不正确。
    • @NoDisplayName 忽略 - 添加逗号,错误消失
    • 这似乎工作得很好!谢谢你们的帮助!!
    猜你喜欢
    • 2023-03-15
    • 2017-02-14
    • 1970-01-01
    • 2011-07-21
    • 2021-07-21
    • 1970-01-01
    • 2015-08-10
    • 2021-03-20
    • 2020-05-19
    相关资源
    最近更新 更多