Comment puis-je join un jeu d'loggings parent et enfant dans un jeu d'loggings?

S'il s'agit d'une question DBA, n'hésitez pas à me le faire savoir.

Nous disposons de données stockées dans une database SQL qui doivent être exscopes, ce qui peut être converti en un nouveau progiciel. À l'heure actuelle, nous avons un jeu d'loggings parent et un jeu d'loggings enfant qui doit être combiné car le nouveau système a la possibilité de suivre ce qui se trouvait dans un jeu d'loggings enfant sur le parent. J'espère que cela a du sens.

Ensemble d'loggings parentaux

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

Ensemble d'loggings pour enfants

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

Idéalement, nous avons besoin d'un file CSV (en fin de count) qui ressemble en quelque sorte:

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

Vous obtenez l'image.

Je ne me soucie pas si cela se fait dans SQL, Excel, Access ou une certaine magie (essayant d'éviter d'écrire un programme), j'essaie de gagner du time qu'il faudrait un membre du personnel pour changer manuellement l'ordre ou le taper. Des idées sur comment rendre cela facile à changer? Nous parlons de 5700 dossiers d'enfants et de 5900 dossiers parentaux. Existe-t-il une magie SQL qui peut faire cela?

J'ai pensé à append chaque colonne individuellement (par exemple (select value from child where id = parent id and code = 'RPM') as RPM ) mais avec 157 codes différents, ce qui n'est pas idéal non plus.

En supposant que vous voulez aller DYNAMIC (pas testé)

 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); 

MODIFIER

Si les colonnes doivent être dans un ordre spécifique

 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 

J'aime la structure de données actuelle beaucoup mieux que celle que vous convertissez, mais si vous devez le faire, vous pouvez utiliser VBA pour parcourir tous les champs et créer une string SQL:

 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 

Cela fonctionne pour les quelques codes que vous avez spécifiés – Je ne sais pas s'il dépassera les limites sur la longueur de string SQL maximale lorsque vous l'exécutez sur tous les champs. Si c'est le cas, vous devrez peut-être déterminer comment segmenter datatables et les faire en quelques morceaux.

C'est ce que j'ai finalement fait, une sorte de fusion de @JohnCappelletti et d'autres personnes sur cette list.

D'abord, j'ai créé une list de tous les codes possibles

 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 

La sortie de cette requête est

 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), ... 

Ensuite, j'ai simplement copié et collé les résultats dans la requête parentale.

 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 

Cela a au less atteint ce que je voulais dire. Les users ont encore le nettoyage à faire, mais c'est mieux que de taper manuellement.

Je pense que vous pouvez l'arrêter dans SQL en utilisant ce qui suit …

 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` 

Essayez de faire une CASE pour chacun des champs dont vous avez besoin en suivant le model.
Le MAX est une fonction agrégée utilisée ici pour éviter des niveaux de regroupement supplémentaires.

Vous pouvez traiter une grande list de codes en saisissant d'abord la list des codes en utilisant …

 SELECT DISTINCT `code` from `child` 

Ensuite, copyz les résultats sur Excel et utilisez la fonction CONCATENATE pour créer les lignes MAX (CASE … … un exemple ici … Excel SQL Building Example

Vous pouvez également créer des lignes en vrac manuellement avec un éditeur de text capable de gérer les modifications de blocs (par exemple, Notepad ++) en tapant simultanément les parties répétées des lignes en mode édition de bloc (ALT + Click & Drag). Vous pouvez également utiliser un peu de search intelligente et replace les opérations pour créer les lignes pour vous aussi.

Enfin, vous pouvez build le SQL en écrivant une petite boucle à l'aide de votre langue préférée et en utilisant la list des codes Distinct, j'ai construit un exemple en utilisant JavaScript, voici un violon pour cela, il devrait être utilisable directement à partir du violon.