如何将父和子logging集合到一个logging集中?

如果这是一个DBA的问题,请随时告诉我。

我们将数据存储在需要导出的SQL数据库中,以便将其转换为新的软件包。 目前,我们有一个父logging集和一个需要组合的子logging集,因为新系统能够跟踪父logging集上的子logging集。 我希望这是有道理的。

父logging集

ID | Description -- | ----------- 1 | Item 1 2 | Item 2 3 | Item 3 

儿童logging集

 Parent ID | Code | Value (string) --------- | ----------- | ------------------- 1 | PSI | 75 1 | SIZE | 2 1/2" 2 | CFM | 9200 2 | BELT | BROWING - A76 2 | RPM | 722 3 | PSI | 45 3 | SIZE | 1" 

理想情况下,我们需要一个CSV文件(最后),看起来像这样:

 ID | Description | PSI | SIZE | CFM | BELT | RPM -- | ----------- 1 | Item 1 2 | Item 2 3 | Item 3 

你得到的照片。

我不在乎是否在SQL,Excel,Access或某些魔术(试图避免编写程序)中完成,我试图节省工作人员手动更改订单或input时间。任何想法如何使这容易改变? 我们正在谈论5700个孩子的logging和5900个父logging。 有一些SQL魔法可以做到这一点吗?

我曾考虑过每个列单独添加(例如(select value from child where id = parent id and code = 'RPM') as RPM ),但有157个不同的代码,这也不是理想的。

假设你想要去dynamic(未testing)

 Declare @SQL varchar(max) = Stuff((Select Distinct ',' + QuoteName(Code) From Child Order by 1 For XML Path('')),1,1,'') Select @SQL = ' Select [ID],[Description],' + @SQL + ' From ( Select A.ID ,A.Description ,B.Code ,B.Value From Parent A Join Child B on (A.ID=B.ParentID) ) A Pivot (max(Value) For [Code] in (' + @SQL + ') ) p' Exec(@SQL); 

编辑

如果列需要按照特定的顺序

 Select A.ID ,A.Description ,PSI = max(case when B.Code='PSI' then B.Value end) ,Size = max(case when B.Code='Size' then B.Value end) ,CFM = max(case when B.Code='CFM' then B.Value end) -- ... more fields From Parent A Join Child B on (A.ID=B.ParentID) Group By A.ID,A.Description 

我喜欢当前的数据结构比转换的要好得多,但是如果你必须这样做的话,你可以使用VBA遍历所有的字段并创build一个SQLstring:

 Function ConvertTable() Set db = CurrentDb() SQL = "Select ParentID" Set RS = db.OpenRecordset("select Code from ChildRS group by Code") RS.MoveFirst Do While Not RS.EOF code = RS.Fields("Code").Value SQL = SQL & ", FIRST(iif(code='" & code & "',value)) as [" & code & "]" RS.MoveNext Loop SQL = SQL & " Into [ConvertedTable] From ChildRS group by ParentID" db.Execute SQL MsgBox ("done") End Function 

这适用于你指定的几个代码 – 我不知道当你在所有的字段上运行时它是否会超过最大SQLstring长度的限制。 如果是这样,你可能需要弄清楚如何分割数据,并做了几件。

这是我最后做的,类似@JohnCappelletti和其他人在这个名单上的合并。

首先我创build了所有可能的代码的列表

 select (REPLACE(REPLACE(REPLACE(c.Code, ' ', '_'), '.',''),'/','_') + ' = max(case when d.Code = ''' + c.Code + ''' then d.Value else '''' end),') as text from code_definitiions c order by Code 

该查询的输出是

 AGMA = max(case when d.Code = 'AGMA' then d.Value1 else '' end), AMB = max(case when d.Code = 'AMB' then d.Value1 else '' end), AMB_T = max(case when d.Code = 'AMB T' then d.Value1 else '' end), ... 

然后我复制并粘贴父查询中的结果。

 select m.ID, m.Description, AGMA = max(case when d.Code = 'AGMA' then d.Value else '' end), AMB = max(case when d.Code = 'AMB' then d.Value else '' end), AMB_T = max(case when d.Code = 'AMB T' then d.Value else '' end), ... (the rest of the codes) from parent m left outer join child d on m.primary_key = d.foreign_key group by m.ID, m.Description order by m.ID 

至less达到了我的意图。 用户仍然有清理工作,但是比手动input要好。

我认为你可以使用下面的SQL来closures它…

 SELECT parent_id AS `ID`, MAX(CASE WHEN `code` = 'PSI' THEN `value` ELSE NULL END) AS `PSI`, MAX(CASE WHEN `code` = 'SIZE' THEN `value` ELSE NULL END) AS `SIZE`, MAX(CASE WHEN `code` = 'CFM' THEN `value` ELSE NULL END) AS `CFM`, MAX(CASE WHEN `code` = 'BELT' THEN `value` ELSE NULL END) AS `BELT`, MAX(CASE WHEN `code` = 'RPM' THEN `value` ELSE NULL END) AS `RPM` FROM `child` GROUP BY `parent_id` 

尝试按照模式为每个需要的字段创build一个CASE。
MAX是一个聚合函数,在这里用来避免额外的分组级别。

你可以处理大量的代码,首先抓住代码列表使用…

 SELECT DISTINCT `code` from `child` 

然后将结果复制到Excel中,并使用CONCATENATE函数来构buildMAX(CASE …行…这里是一个示例… Excel SQL构build示例

您还可以通过在块编辑模式(ALT +单击并拖动)中同时input线条的重复部分,使用能够处理块编辑的文本编辑器(例如Notepad ++)手动批量生成线条。 您也可以使用一些巧妙的查找和replace操作来为您build立线路。

最后,您可以通过使用您最喜欢的语言编写一个小循环来构buildSQL,并使用Distinct代码列表,我使用JavaScript构build了一个示例,这里是一个小提琴 ,它应该可以直接从小提琴中使用。