如何将父和子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了一个示例,这里是一个小提琴 ,它应该可以直接从小提琴中使用。