当前位置: 首页 > 面试题库 >

SQL Server:将几行数据合并为一行

松亦
2023-03-14
问题内容

我想要做的是合并几行数据,以便在Transact-SQL或SSIS中将其显示为单行。因此,例如:

制作:

REF  ID   Title Surname     Forename    DOB          Add1            Postcode
------------------------------------------------------------------------------------------    
D    10   MR    KINGSTON    NULL        15/07/1975   3 WATER SQUARE  NULL
T    10   NULL  NULL        BOB         NULL         NULL            NULL
T    10   MRS   NULL        NULL        NULL         NULL            TW13 7DT

到这个:

REF  ID   Title Surname    Forename   DOB          Add1            Postcode
----------------------------------------------------------------------------------    
D    10   MRS   KINGSTON   BOB        15/07/1975   3 WATER SQUARE  TW13 7DT

因此,我所做的就是将值合并在一起,而忽略了null值。(D =数据; T =更新)

任何建议将是最欢迎的。

谢谢。


问题答案:

这将起作用,但是由于没有标识或日期时间列-无法找到哪个更新行是较新的。因此,如果同一列上有更多更新,那么我只需按字母/数字(MIN)来选择第一个。

WITH CTE AS 
(
    SELECT ID, REF, MIN(Title) Title, MIN(Surname) Surname, MIN(Forename) Forename, MIN(DOB) DOB, MIN(Add1) Add1, MIN(Postcode) Postcode
    FROM Table1
    GROUP BY id, REF
)
SELECT 
    d.REF
  , d.ID
  , COALESCE(T.Title, d.TItle) AS Title
  , COALESCE(T.Surname, d.Surname) AS Surname
  , COALESCE(T.Forename, d.Forename) AS Forename
  , COALESCE(T.DOB, d.DOB) AS DOB
  , COALESCE(T.Add1, d.Add1) AS Add1
  , COALESCE(T.Postcode, d.Postcode) AS Postcode
FROM CTE d 
INNER JOIN CTE t ON d.ID = t.ID AND d.REF = 'D' AND t.REF = 't'

SQLFiddle演示

如果可以添加标识列,我们可以重写CTE部分以使其更准确。

编辑:

如果我们有标识列,并且将CTE重写为递归,则实际上可以删除整个查询的其他部分。

WITH CTE_RN AS 
(
    --Assigning row_Numbers based on identity - it has to be done since identity can always have gaps which would break the recursion
    SELECT *, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY IDNT DESC) RN FROM dbo.Table2
)
,RCTE AS 
(
    SELECT  ID ,
            Title ,
            Surname ,
            Forename ,
            DOB ,
            Add1 ,
            Postcode ,
            RN FROM CTE_RN WHERE RN = 1 -- taking the last row for each ID
    UNION ALL
    SELECT r.ID,
        COALESCE(r.TItle,p.TItle), --Coalesce will hold prev value if exist or use next one
        COALESCE(r.Surname,p.Surname),
        COALESCE(r.Forename,p.Forename),
        COALESCE(r.DOB,p.DOB),
        COALESCE(r.Add1,p.Add1),
        COALESCE(r.Postcode,p.Postcode),
        p.RN
    FROM RCTE r
    INNER JOIN CTE_RN p ON r.ID = p.ID AND r.RN + 1 = p.RN --joining the previous row for each id
)
,CTE_Group AS 
(
    --rcte now holds both merged and unmerged rows, merged is max(rn)
    SELECT ID, MAX(RN) RN FROM RCTE
    GROUP BY ID  
)
SELECT r.* FROM RCTE r
INNER JOIN CTE_Group g ON r.ID = g.ID AND r.RN = g.RN

SQLFiddle演示



 类似资料:
  • 问题内容: 我正在使用SQL Server2008。我具有下表中的数据: 我想以这种格式获取数据: 我怎样才能做到这一点? 问题答案: 使用PIVOT您可以执行以下操作 产生 查看有效的Data.SE示例 在不支持PIVOT的数据库中,您可以改为对表进行多次联接。尽管您可能还是想这样做,但是正如GBN所指出的那样,因为我们没有使用聚合。 查看有效的Data.SE示例

  • 问题内容: 这个问题已经在这里有了答案 : 8年前关闭。 可能重复: 连接行值T-SQL 我是SQL Server的新手,曾经尝试过一些互联网上建议的技术,例如使用临时变量,XML路径等,但是所有这些都不满足我的要求。 我正在使用Toad for SQL Server 5.5版创建SQL脚本,而我用来查询数据库服务器的帐户仅具有READ访问权限。因此不能使用我相信的声明。 表名: 预期产量: 问题

  • 问题内容: 我对Oracle Sql有疑问, 如果我有一个8列的名为A的数据: 我可以这样将其转换为表B: 这是将列(周日至周六)合并为一个名为“星期几”的新列 我该怎么办?谢谢! 问题答案: 您可以使用: Oracle安装程序 : 查询 : 输出 :

  • 问题内容: 我正在尝试不同的JOIN查询,但没有得到想要的结果。 我有2张桌子: 我找不到想要的结果。 我想得到以下结果: 问题答案: 您不能具有这样的动态列数,但是可以 将数据连接 成字符串: 或者您可以使用或手动 旋转行( 我更喜欢后一种方法,对我来说似乎更灵活,但是在某些情况下可以大大减少代码量): 您还可以将前面的语句转换为 动态SQL, 如下所示:

  • 问题内容: 假设我在MySQL数据库中有两个表。 表格1: 表2: 从数据库中选择行时,是否有任何方法可以将第二个表中的行作为列连接到第一个表中? 直接从MySQL查询获得的期望结果是: 谢谢你的帮助! 问题答案: 这种数据转换类型称为PIVOT。MySQL没有枢轴函数,但是您可以使用带有表达式的聚合函数来复制它: 请参阅带有演示的SQL Fiddle。 这也可以使用您的多个联接来编写,并且您将在

  • 问题内容: 我们有些SQL杂语。说我有一个看起来像这样的结果… 61E77D90-D53D-4E2E-A09E-9D6F012EB59C | A 61E77D90-D53D-4E2E-A09E-9D6F012EB59C | B 61E77D90-D53D-4E2E-A09E-9D6F012EB59C | C 61E77D90-D53D-4E2E-A09E-9D6F012EB59C | D 7ce9