2009-07-31 9 views
3

J'ai deux tables avec les colonnes suivantes (colonnes identiques dans les deux tables):Fusion de deux tables

  1. FUNCTIONNAME,
  2. FrequencyCount

Je veux fusionner ces deux tables en finale table avec colonnes:

  1. Nom Fonction
  2. Base de comptage de fréquence
  3. Par rapport Fréquence de comptage
  4. Delta du nombre de fréquences

opération de fusion devrait se faire comme suit:

  • Si [FunctionName] est au tableau 1 et non pas dans Tableau2,

    [Base Frequency Count] = Table1.[FrequencyCount] 
    [Compared Frequency Count] = 0 
    [Delta of Frequency Count] = Table1.[FrequencyCount] 
    
  • Si [NomFonction] est dans le Tableau 2 et PAS dans Tableau 1,

    [Base Frequency Count] = 0   
    [Compared Frequency Count] = Table2.[FrequencyCount] 
    [Delta of Frequency Count] = Table2.[FrequencyCount] 
    
  • Si [FunctionName] est à la fois dans Table1 et Table2,

    [Base Frequency Count] = Table1.[FrequencyCount]   
    [Compared Frequency Count] = Table2.[FrequencyCount] 
    [Delta of Frequency Count] = Table1.[FrequencyCount]-Table2.[FrequencyCount] 
    

Il est souhaitable que la requête a de bonnes performances sans minimum. des jointures. Ce serait génial si quelqu'un peut donner de bons conseils.

Répondre

1
SELECT * 
    INTO new_table_name 
    FROM (SELECT t.frequencycount 'Base Frequency Count', 
       0 'Compared Frequency Count', 
       t.frequencycount 'Delta of Frequency Count' 
      FROM TABLE1 t 
      JOIN TABLE2 t2 ON t2.functionname != t.functionname 
     UNION 
     SELECT 0 'Base Frequency Count', 
       t2.frequencycount 'Compared Frequency Count', 
       t2.frequencycount 'Delta of Frequency Count' 
      FROM TABLE2 t2 
      JOIN TABLE1 t ON t.functionname != t2.functionname 
     UNION 
     SELECT t.frequencycount 'Base Frequency Count', 
       t2.frequencycount 'Compared Frequency Count', 
       t.frequencycount - t2.frequencycount 'Delta of Frequency Count' 
      FROM TABLE1 t 
      JOIN TABLE2 t2 ON t.functionname = t2.functionname) 
+0

C'était parfait! Merci pour votre réponse. Mais il y a un problème que j'ai remarqué en exécutant cette requête. Lorsque j'insère 'Nom de la fonction' dans la table résultante (nouveau_nom_table), la requête prend environ 1,49min à exécuter par rapport à 0,3 seconde lorsque 'Nom de la fonction' n'est pas sélectionné. Des commentaires à ce sujet? –

+0

Avez-vous un index sur FunctionName dans les deux tables à partir desquelles vous copiez? –

+0

No. 'Nom de fonction' ne sont pas uniques dans la table. –

0

Je ne sais pas si ce serait plus lent que la solution de rexem (je ne l'ai pas le benchmark). Mais cela pourrait être plus facile pour vous de lire. Les performances peuvent être considérablement améliorées en sélectionnant basé sur les clés primaires au lieu de FunctionName.

--TABLE 1 
SELECT FunctionName, FrequencyCount AS Base, 0 AS Compared, FrequencyCount AS Delta 
FROM TableOne 
WHERE FunctionName NOT IN (SELECT FunctionName FROM TableTwo) 
UNION 

--TABLE 2 
SELECT FunctionName, 0 AS Base, FrequencyCount AS Compared, FrequencyCount AS Delta 
FROM TableTwo 
WHERE FunctionName NOT IN (SELECT FunctionName FROM TableOne) 
UNION 

--DELTA 
SELECT FunctionName, 
(SELECT FrequencyCount FROM TableOne WHERE FunctionName = DeltaTable.FunctionName) AS Base, 
(SELECT FrequencyCount FROM TableTwo WHERE FunctionName = DeltaTable.FunctionName) AS Compared, 
(SELECT FrequencyCount FROM TableOne WHERE FunctionName = DeltaTable.FunctionName) - (SELECT FrequencyCount FROM TableTwo WHERE FunctionName = DeltaTable.FunctionName) AS Delta 
FROM TableOne DeltaTable 
WHERE FunctionName IN (SELECT FunctionName FROM TableOne) 
AND FunctionName IN (SELECT FunctionName FROM TableTwo) 

modification Delta

--DELTA 
SELECT One.FunctionName, 
One.FrequencyCount AS Base, 
Two.FrequencyCount AS Compared, 
One.FrequencyCount - Two.FrequencyCount AS Delta 
FROM TableOne One 
INNER JOIN TableTwo Two 
    ON One.FunctionName = Two.FunctionName 
+0

Les sous-requêtes dans la clause SELECT vont être un cauchemar de performance - elles sont exécutées pour chaque enregistrement dans le jeu de résultats. La clause IN est supposée être plus lente que l'utilisation d'EXISTS (qui s'exécute sans doute plus lentement que l'utilisation de JOINs). –

+0

Delta pourrait être changé à un tel: --DELTA SELECT One.FunctionName, One.FrequencyCount AS Base, Two.FrequencyCount AS Comparée, One.FrequencyCount - Two.FrequencyCount AS Delta DE TableOne Un INNER JOIN TableTwo Deux \t ON One.FunctionName = Two.FunctionName Ce qui éliminerait les sous-sélections ... Plus proche de votre solution avec les jointures. Ce que Atul ne devrait pas avoir peur de nécessairement si les bons index sont sur les tables. –

2
SELECT ISNULL(fn.FunctionName, fc.FunctionName) AS FunctionName, 
     ISNULL(fn.FrequencyCount, 0) AS BaseFrequency, 
     ISNULL(fc.FrequencyCount, 0) AS ComparedFrequencyCount, 
     COALESCE((fn.FrequencyCount - fc.FrequencyCount), fn.FrequencyCount, fc.FrequencyCount) AS DeltaOfFrequencyCount 
INTO FinalTable 
FROM FunctionName fn FULL OUTER JOIN FrequencyCount fc ON fn.FunctionName = fc.FunctionName 

Notez que le COALESCE se traduira par une valeur nulle dans la première expression (de passer à la suivante dans la chaîne) si l'une ou fn.FrequencyCount fc. FrequencyCount est null (en SQL, valeur - null = null).

+0

Maintenant que j'y pense, les instructions CASE peuvent être supprimées aussi et remplacées par ISNULL. –