在 SQL 中将父/子关系记录展平为 1 行(更新)

Posted

技术标签:

【中文标题】在 SQL 中将父/子关系记录展平为 1 行(更新)【英文标题】:Flattening out parent/child relationship records into 1 row in SQL (Updated) 【发布时间】:2020-04-09 23:18:52 【问题描述】:

我在同一个订单号上最多有 3 条记录(单击下面的链接查看图片)。我需要将其展平为 1 行,因为我的目标表具有非规范化(展平)架构。我需要对所有 3 个集合执行此操作——firstcolX、secondcolX、thirdcolX,所以它只有 1 行。 1:N 关系是订单(父)到订单行项目(子)

Please click here to see desired outcome

谢谢,非常感谢您对此提供的任何帮助。 FWIW,我正在使用 SSIS 将数据从 SQL 源移动到 SQL 目标。我试过 PIVOT,但我们不希望行数据作为列名。

【问题讨论】:

你怎么知道那些行有父子关系?示例数据显示它们之间没有关系。 换个说法,给定firstcol1a中的K0861、k0108和23434的值,我们怎么知道第一个值是什么?如果结果行是 23434、k0861、k0108 会不会不正确? @billinkc,我更新了图片以帮助更好地解释。但是,是的,要回答你的问题,是的,他们需要按照我试图在图片中展示的方式进行。由于我们正在映射这些值,因此我们需要数据保持一致 你如何决定列顺序?这是第一列,第二列,第三列。 @venkataraman R 它需要变平的方式是第 1 行值进入 A 列(已经存在),第 2 行值进入 B 列,第 3 行值进入在 C 列中 【参考方案1】:

您可以生成 RowNumber,然后使用派生表来实现这一点。

;WITH CTE_TableName AS
(
SELECT *,RowNumber() over(Partition by myOrderNum ORDER BY MyOrderNum) AS rnk
FROM TableName
)
SELECT myOrderNum,firstcol1A
,(SELECT firstCol1A FROM CTE_TableName WHERE rnk =2 AND OrderNum = c.OrderNum) AS firstCol1B
,(SELECT firstCol1A FROM CTE_TableName WHERE rnk =3 AND OrderNum = c.OrderNum) AS firstCol1C
,SecondCol2A
,(SELECT SecondCol2A FROM CTE_TableName WHERE rnk =2 AND OrderNum = c.OrderNum) AS ,SecondCol2B
,(SELECT SecondCol2A FROM CTE_TableName WHERE rnk =3 AND OrderNum = c.OrderNum) AS ,SecondCol2C
,thirdCol3A
,(SELECT thirdCol3A FROM CTE_TableName WHERE rnk =2 AND OrderNum = c.OrderNum) AS thirdCol3B
,(SELECT thirdCol3A FROM CTE_TableName WHERE rnk =3 AND OrderNum = c.OrderNum) AS thirdCol3C
FROM CTE_TableName AS c;

【讨论】:

【参考方案2】:

我会像 Venkataram 那样做,但在连接中而不是相关子查询中做工作:

;WITH cte AS
(
SELECT *,RowNumber() over(Partition by myOrderNum ORDER BY MyOrderNum) AS rnk
FROM TableName
)
Select cte1.myOrderNum 
   ,cte1.FirstCol1A 
   ,cte2.FirstCol1A as FirstCol1B
   ,cte3.FirstCol1A as FirstCol1C
...
from cte cte1
    join cte cte2 on cte2.myOrderNum = cte1.myOrderNum and cte2.rnk=2
    join cte cte3 on cte3.myOrderNum = cte1.myOrderNum and cte3.rnk=3
where cte1.rnk=1

编辑:将 ordernum 更改为 MyOrderNUm

【讨论】:

嗨@KeithL 在您的示例查询中,您从第二个 Select 语句中的哪里获取 cte1.ordernum、cte2.orderNum 和 cte3.orderNum 字段?在我的示例屏幕截图中,没有 ordernum 列(只有 myordernum)。当我尝试插入我的字段值时,我收到一个无效的列名错误 把名字改成MyOrderNum

以上是关于在 SQL 中将父/子关系记录展平为 1 行(更新)的主要内容,如果未能解决你的问题,请参考以下文章

在 SQL Server 中将记录的状态设置为 false 之前检查记录的子记录

Rails:在 HABTM 关系中将子项从大型记录集添加到父模型的 UI

SQL从每个父行的子行返回最大值

如何在 Vue JS 中将更新的值从父组件发送到子组件?

Hive - 将层次结构表展平为级别

使用 LINQ 展平列表列表以获取父/子列表