2013-06-27 51 views
7

Tôi có một cột (varchar400) theo hình thức sau đây trong một bảng SQL:Vấn đề cú pháp SQL Server. Kết hợp Pivot, phân tích cú pháp XML và THAM GIA

Info 
User ID=1123456,Item ID=6685642 

cột này được sử dụng để lưu trữ các thuộc tính của sản phẩm trong cơ sở dữ liệu của chúng tôi, và như vậy trong khi tôi chỉ quan tâm đến User ID và ID mặt hàng, có thể có những thông tin không cần thiết lưu trữ ở đây, ví dụ:

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

và vì vậy tôi đã một truy vấn SQL như sau:

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

Bây giờ, này trả về một cách chính xác cho tôi một cột như sau:

UserID 
1 
2 
3 
4 
5 

Bây giờ tôi có một bảng, Table2, nắm giữ các lệnh người dùng đã thực hiện. Tôi muốn sử dụng UserID như một tham chiếu trong bảng này, và vì vậy thay vì chỉ trả về UserID, tôi sẽ trả về các hàng trên bảng này, nơi UserID mà tôi đã trả về ở trên bằng các hàng trong bảng này.

Vì vậy, thay vì ở trên, chúng tôi nhận được:

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

2 câu hỏi - làm thế nào tôi có thể thực hiện lệnh JOIN hoặc làm một subquery để kết hợp hai bảng, tôi không thể tìm ra cách để làm điều này với cú pháp chính xác . Thứ hai, tôi đã viết một số nhận xét về truy vấn của tôi ở trên cho thấy cách tôi hiểu truy vấn đang hoạt động. Họ có đúng không?

Trả lời

4

Hoàn toàn có thể là tôi thiếu điều gì đó với câu hỏi của bạn, nhưng có vẻ như bạn chỉ có thể mở rộng truy vấn hiện tại của mình theo cách sau. Đây vẫn sử dụng CTE và PIVOT, nhưng truy vấn PIVOT được đặt trong một subquery cho phép bạn tham gia vào 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; 

Xem SQL Fiddle with Demo

+0

Cảm ơn cho điều này! Sẽ đưa nó vào buổi tối thử nghiệm, nhưng điều này có vẻ tốt :). Nhận xét của tôi ở trên có chính xác không? –

+0

Tôi sẽ đi với câu trả lời này .. – MarmiK