2010-07-16 5 views
1

Ma table de base est comme:T-SQL pour modifier les données d'une table et l'insérer dans une autre table

ColumnA|ColumnB 
--------------- 
    A | C1 
    A | C2 
    A | C3 
    B | C1 
    B | C3 
    C | C4 

Je veux lire les enregistrements de la table de base et de l'écrire dans le tableau ci-dessous:

ColumnA | C1 | C2 | C3 | C4 
---------------------------- 
    A | Y | Y | Y | N 
    B | Y | N | Y | N 
    C | N | N | N | Y 

Je ne veux pas utiliser un curseur, mais je ne sais pas si c'est possible ou non.

Merci

+0

quelque chose comme un tableau croisé dynamique, non? – MJB

+0

oui je pense mais je ne sais pas comment puis-je utiliser ici – oshin

+0

devrait C-> C4 être Y? essayez-vous de construire une table de vérité ou simplement obtenir la sortie affichée? –

Répondre

1

Un (généralement rapide) façon serait group by:

insert NewTable (ColumnA, C1, C2, C3, C4) 
select ColumnA 
,  IsNull(max(case when ColumnB = 'C1' then 'Y' end), 'N') 
,  IsNull(max(case when ColumnB = 'C2' then 'Y' end), 'N') 
,  IsNull(max(case when ColumnB = 'C3' then 'Y' end), 'N') 
,  IsNull(max(case when ColumnB = 'C4' then 'Y' end), 'N') 
from OldTable 
group by 
     ColumnA 

Une autre façon est sous-requêtes, comme:

insert NewTable (ColumnA, C1, C2, C3, C4) 
select src.ColumnA 
,  case when exists (select * from OldTable ot 
          where ot.ColumnA = src.ColumnA and ot.ColumnB = 'C1') 
        then 'Y' else 'N' end 
,  case when exists (select * from OldTable ot 
          where ot.ColumnA = src.ColumnA and ot.ColumnB = 'C2') 
        then 'Y' else 'N' end 
,  case when exists (select * from OldTable ot 
          where ot.ColumnA = src.ColumnA and ot.ColumnB = 'C3') 
        then 'Y' else 'N' end 
,  case when exists (select * from OldTable ot 
          where ot.ColumnA = src.ColumnA and ot.ColumnB = 'C4') 
        then 'Y' else 'N' end 
from (
     select distinct ColumnA 
     from OldTable 
     ) src 

Ou, adapté de Chris La réponse du plongeur, avec pivot:

select ColumnA 
,  case when C1 > 0 then 'Y' else 'N' end C1 
,  case when C2 > 0 then 'Y' else 'N' end C2 
,  case when C3 > 0 then 'Y' else 'N' end C3 
,  case when C4 > 0 then 'Y' else 'N' end C4 
from OldTable src 
pivot (
     count(ColumnB) 
     for ColumnB IN ([C1], [C2], [C3], [C4]) 
     ) pvt 
+0

+1. C'est plus facile si/quand le nombre de colonnes à pivoter est connu au moment du design, et est assez petit pour gérer avec copier/coller ces sous-requêtes. –

+0

dans le groupe par pourquoi utilisez-vous MAX? – oshin

+0

@oshin: Vous devez spécifier un moyen pour la base de données d'agréger les valeurs de plusieurs lignes. L'expression dans 'max()' renvoie 'Y' pour une correspondance et 'null' pour aucune correspondance. Le 'max()' de cela est 'Y' si une ligne correspondante a été trouvée, et' null' sinon. – Andomar

0

en supposant que vous pouvez sélectionner les informations que vous le souhaitez, vous pouvez écrire l'insert à la suite de cette sélection.

+0

avez-vous lu la question à tous mon ami? !! – oshin

2

Jetez un coup d'œil à la commande PIVOT. De là, vous pouvez faire un INSERT INTO ... SELECT ...

SELECT ColumnA, [C1], [C2], [C3], [C4] 
FROM (SELECT * FROM table) t 
PIVOT 
(
Count(ColumnB) 
FOR ColumnB IN ([C1], [C2], [C3], [C4]) 
) As Pvt 
+0

Comme j'ai juste besoin de Y ou N, comment puis-je utiliser une déclaration de cas ici? Je suis en train de tester le nombre de cas (columnB) = 0 puis 'N' ELSE 'Y' END mais j'obtiens une erreur: Syntaxe incorrecte près du mot clé 'case'. – oshin

+0

@oshin: le pivot est inflexible dans la demande de () '. J'ai ajouté une version pivot à ma réponse qui fonctionne autour de cela, mais veuillez accepter la réponse de Chris Diver si vous préférez pivoter :) – Andomar

+0

Vous devriez mettre un cas autour de chacun des '[Cx]' dans l'instruction select. –

Questions connexes