2013-06-27 9 views
7

ho una colonna (varchar400) il seguente modulo in una tabella SQL:Problema di sintassi SQL Server. La combinazione di Pivot, parse XML e JOIN

Info 
User ID=1123456,Item ID=6685642 

Questa colonna viene utilizzata per memorizzare gli attributi dei prodotti nel nostro database, e così mentre io sono riguarda solo ID utente e l'ID del lotto, ci possono essere memorizzate informazioni superflue qui, per esempio:

Info 
    Irrelevant ID=666,User ID=123124,AnotherIrrelevantID=1232342,Item ID=1213124 

e così ho una query SQL come segue:

-- convert info column to xml type 
; with cte as --imports a library of common table expressions 
(
    select TOP 1000 cast('<info ' + REPLACE(REPLACE(REPLACE(REPLACE(OtherInformation,' ', ''),',', '" '),'=','="'),'.','') + '" />' as XML) info, --puts the OtherInformation column into well formed XML 
    ROW_NUMBER() over (order by TableID) id --returns all rows?? 
    FROM Table 
    WHERE TableEnum=51 
) 
SELECT DISTINCT UserID from --selects unique user ids from our returned xml 
(
     select T.N.value('local-name(.)', 'varchar(max)') as Name, --selects all attributes returned in varchar(max) format as Name 
     T.N.value('.', 'varchar(max)') as Value, id --Selects all values returned 
     from cte cross apply info.nodes('//@*') as T(N) -- from the XML we created above 
) v 
pivot (max(value) for Name in ([UserID])) p --creates a pivot table on Name, separating all of the attributes into different columns 

Ora, questo mi restituisce correttamente un colonne come segue:

UserID 
1 
2 
3 
4 
5 

ora ho un altro tavolo, Table2, che detiene gli ordini che un utente ha fatto. Voglio usare l'UserID come riferimento in questa tabella, e così invece di restituire solo UserID, restituirò le righe su questa tabella in cui l'ID utente che ho restituito sopra equivale alle righe in questa tabella.

Così, invece di sopra, otteniamo:

UserID Table2Col Table2Col2 
2    Info  Info 
5    Info  Info 
5    Info2  Info2 
5    Info3  Info3 

2 domande - come posso eseguire un JOIN o fare una sottoquery per unire le due tabelle, io non riesco a capire come fare questo con la sintassi corretta . In secondo luogo, ho scritto alcuni commenti sulla mia query sopra che mostrano come capisco che la query funzioni. Sono corretti?

risposta

4

È possibile che manchi qualcosa con la domanda, ma sembra che si possa semplicemente espandere la query esistente nel seguente modo. Questo utilizza ancora il CTE ed il perno, ma la query PIVOT è collocato in una sottoquery, che permette di unire a table2:

; with cte as --imports a library of common table expressions 
(
    select TOP 1000 cast('<info ' + REPLACE(REPLACE(REPLACE(REPLACE(OtherInformation,' ', ''),',', '" '),'=','="'),'.','') + '" />' as XML) info 
     , ROW_NUMBER() over (order by TableID)) id 
    FROM yourtable 
) 
select d.userid, t2.col1, t2.col2 
from 
(
    SELECT DISTINCT UserID 
    from 
    (
    select T.N.value('local-name(.)', 'varchar(max)') as Name, 
     T.N.value('.', 'varchar(max)') as Value, id 
    from cte 
    cross apply info.nodes('//@*') as T(N) 
) v 
    pivot 
    (
    max(value) 
    for Name in ([UserID]) 
) p 
) d 
inner join table2 t2 
    on d.userid = t2.userid; 

Vedi SQL Fiddle with Demo

+0

Grazie per questo! Lo metterò alla prova stasera, ma questo sembra buono :). I miei commenti sopra sono corretti? –

+0

Vado con questa risposta .. – MarmiK