【问题标题】:T-SQL concatenate multiple records into one recordT-SQL 将多条记录连接成一条记录
【发布时间】:2016-06-11 18:57:03
【问题描述】:

我想根据 PolNo、Year、Platform、Number 将下表中的记录合并为一条记录。

| PolNo | YEAR | Platform | Number | Record | memo                |
|-------|------|----------|--------|--------|---------------------|
| 123   | 2010 | pc       | 1      | 1      | The user had issues |
| 123   | 2010 | pc       | 1      | 2      | with the os.        |
| 123   | 2009 | pc       | 2      | 1      | Replaced RAM        |
| 123   | 2010 | mac      | 1      | 1      | Ordered new CDs     |
| 564   | 2009 | mac      | 1      | 1      | Broken CD TRAY      |
| 564   | 2010 | mac      | 1      | 1      | USB port dead       |
| 564   | 2010 | pc       | 1      | 1      | Ordered replacement |
| 564   | 2010 | pc       | 1      | 2      | laptop              |

记录将合并为一条记录(记录列不会结转)。同时,PolNo、Year、Platform 和 Number 被连接成一个 ID,而不是单独的列。

| ID  | YEAR | Platform | memo                             |
|-----|------|----------|----------------------------------|
| 123 | 2010 | pc-1     | The user had issues with the os. |
| 123 | 2009 | pc-2     | Replaced RAM                     |
| 123 | 2010 | mac-1    | Ordered new CDs                  |
| 564 | 2009 | mac-1    | Broken CD TRAY                   |
| 564 | 2010 | mac-1    | USB port dead                    |
| 564 | 2010 | pc-1     | Ordered replacement laptop       |

如您所见,我将上面第 1 行和第 6 行的记录合并到一个连续的备注字段中。然而,我有一些备忘录字段有 21 或 22 条记录要组合/加入。

不知道我将如何做到这一点。

思考光标,但我没有太多经验,听说它没有效果。该表有大约 64k 行要操作(其中 22k 有不止一条记录)

【问题讨论】:

  • 欢迎使用 StackOverflow:如果您发布代码、XML 或数据示例,在文本编辑器中突出显示这些行并单击“代码示例”按钮 ({ } ) 在编辑器工具栏上以很好地格式化和语法突出显示它!
  • 会的,谢谢 Marc...我的强迫症让我想为这个编辑器格式化它! :p

标签: sql-server tsql


【解决方案1】:

您可以使用旧的“FOR XML”技巧来聚合记录文本:

CREATE TABLE #Records
(
    PolNo SMALLINT
    , Year SMALLINT
    , Platform NVARCHAR(16)
    , Number TINYINT
    , Record TINYINT
    , Memo NVARCHAR(256)
);

INSERT INTO #Records(PolNo, Year, Platform, Number, Record, Memo)
VALUES
    (123, 2010, 'pc', 1, 1, 'The user had issues')
    ,(123, 2010, 'pc', 1, 2, 'with the os.')
    ,(123, 2009, 'pc', 2, 1, 'Replaced RAM')
    ,(123, 2010, 'mac', 1, 1, 'Ordered new CDs')
    ,(564, 2009, 'mac', 1, 1, 'Broken CD TRAY')
    ,(564, 2010, 'mac', 1, 1, 'USB port dead')
    ,(564, 2010, 'pc', 1, 1, 'Ordered replacement')
    ,(564, 2010, 'pc', 1, 2, 'laptop')

SELECT *
FROM #Records;

WITH RecordIdentifier AS
(
    SELECT PolNo, Year, Platform, Number
    FROM #Records
    GROUP BY PolNo, Year, Platform, Number
)

SELECT CONCAT(PolNo, '-', Year, '-', Platform, '-', Number) AS Id
    , (SELECT ' ' + Memo
            FROM #Records forAggregation
            WHERE forAggregation.PolNo = record.PolNo
                AND forAggregation.Year = record.Year
                AND forAggregation.Platform = record.Platform
                AND forAggregation.Number = record.Number
            ORDER BY forAggregation.Record
            FOR XML PATH ('')
            ) AS Memo
FROM RecordIdentifier record
ORDER BY Id

DROP TABLE #Records

【讨论】:

  • 您在使用“FROM #Records forAggregation”的选择中迷失了我。我将其视为临时表的别名,但在下面您使用的是语句“AND forAggregation.Year = record.Year”。 record.Year 表在哪里定义?您没有调用临时表#Record.Year,而只是没有哈希的名称。顺便说一句,我喜欢你的例子,它在学习方面很有意义......我是 XML PATH 的新手。
  • 内部选择(forAggregation)能够访问它的“父”('record')——'record'是外部的,“FROM RecordIdentifer record ORDER BY Id”
  • 这太棒了!我很享受这正在推动的学习。我需要的是让这个输出填充一个新表(b/c 这是迁移的一部分)。我一直在研究如何将数据插入到现有表中。
  • 您可以使用SELECT 语句作为INSERT 的来源。例如INSERT INTO dbo.YourTable(Col1, Col2) SELECT Col1, Col2 FROM Source
  • 与 RecordIdentifier AS (SELECT PolNo, Year, Platform, Number FROM #Records GROUP BY PolNo, Year, Platform, Number) INSERT INTO ExternalTable (ID, COMMENT) SELECT CONCAT... -- 谢谢马克!它比我希望的更好!光滑! :)
猜你喜欢
  • 2016-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-24
  • 2019-02-18
  • 1970-01-01
  • 2017-01-02
相关资源
最近更新 更多