在 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 之前检查记录的子记录