Tôi đang làm việc trên một truy vấn SQL bằng cách sử dụng pvots với cột động trong SQL Server (T-sql). Thay vì gửi truy vấn dài dòng của tôi, tôi sẽ minh họa sự cố của tôi với mô hình được đơn giản hóa.Pivots với cột động trong SQL Server
tôi tạo 2 bảng: Table1 và Table2 và cư chúng với một vài mục như sau:
Table1:
Col_ID1 ............ ... Col_Name
1 ......................... Jan-11
2 ........ ................. Feb-11
3 ......................... Mar-11
Table2:
Col_ID2 ...... Tài khoản ..... Tên tài khoản ...... Số tiền
1 ............... 121 ......... ..Electricity ............ 10000
2 ............... 121 ........... Điện. ........... 20000
3 ............... 121 ........... Điện ............ 30000
1 ............... 122 ........... Điện thoại .............. 100
2. .............. 122 ........... Điện thoại .............. 200
3 ... ............ 122 ........... Điện thoại .............. 300
Tôi đang tạo Pivot, nhưng tôi muốn các tên cột được tạo theo tham số (dựa trên các ngày được nhập từ các đầu vào s creen) và không được mã hóa cứng.
Các truy vấn dưới đây hoạt động tốt, nhưng chỉ đưa ra một vài cột như foll:
Jan-11 ........... Feb-11 ........ ... Mar-11
10,000.00 20,000.00 ...... ...... 30,000.00
100,00 ............... 200.00 .... ....... 300.00
Tôi cũng muốn truy vấn trả lại các cột mô tả, như foll:
Tài khoản ........... Tên tài khoản ........... Jan-11 ............ Feb-11 .. ............ Mar-11
121 ................. Điện ............ ...... 10.000.00 ...... 20.000.00 .......... 30,000.00
122 ................. Điện thoại .. ................... 100.00 ........... 200.00 ............. 300.00
Ai đó có thể giúp tôi sửa đổi truy vấn để đạt được mục tiêu không?
Truy vấn này là một sự thích nghi của các bài viết sau đây được viết bởi Tiến sĩ Andras trong Tháng Chín 2007. http://www.simple-talk.com/community/blogs/andras/archive/2007/09/14/37265.aspx
Có người nhận xét rằng các mã có thể phải chịu tấn công Injection và đề xuất sử dụng Quotename chức năng thay vì concatenating dấu ngoặc vuông .
Bạn có thể giải thích cách sử dụng Quotename trong truy vấn của tôi không.
Cảm ơn rất nhiều,
Leon Lai .
.
.
Dưới đây là truy vấn của tôi:
------------------------ tạo & populate table1 ---------- ----------------------
CREATE TABLE Table1
(Col_ID1 INT,
Col_Name varchar(10))
INSERT INTO Table1 VALUES (1, 'Jan-11')
INSERT INTO Table1 VALUES (2, 'Feb-11')
INSERT INTO Table1 VALUES (3, 'Mar-11')
--------------------- ---- tạo & populate table2 ----------------------------------
CREATE TABLE Table2
(Col_ID2 INT,
Account varchar(10),
AccountName varchar(20),
Amount numeric(18,6))
INSERT INTO Table2 VALUES (1, 121, 'Electricity', 10000)
INSERT INTO Table2 VALUES (2, 121, 'Electricity', 20000)
INSERT INTO Table2 VALUES (3, 121, 'Electricity', 30000)
INSERT INTO Table2 VALUES (1, 122, 'Telephone', 100)
INSERT INTO Table2 VALUES (2, 122, 'Telephone', 200)
INSERT INTO Table2 VALUES (3, 122, 'Telephone', 300)
- --------------------------------- tạo các tiêu đề cột -------------- -----
DECLARE @cols NVARCHAR(2000)
SELECT @cols = STUFF((SELECT DISTINCT TOP 100 PERCENT
'],[' + t2.Col_Name
FROM Table1 AS t2
ORDER BY '],[' + t2.Col_Name
FOR XML PATH('')
), 1, 2, '') + ']'
------------------------------------- create @query --- -------------------
DECLARE @query NVARCHAR(4000)
SET @query = N'SELECT '+
@cols +'
FROM
------------------------ --subquery -----
(SELECT
t1.Col_Name,
t2.Account,
t2.Amount
FROM Table1 AS t1
JOIN Table2 AS t2 ON t1.Col_ID1 = t2.Col_ID2
) p
-------------------- trục ------------ -------------
PIVOT
(
Sum ([Amount])
FOR Col_Name IN
('+
@cols +')
) AS pvt '
---------------------- exec & thả ----------
EXECUTE(@query)
drop table table1
drop table table2
=== ================================================== ==
Hi Philip,
Cảm ơn bạn đã trả lời.
Truy vấn được đề xuất của bạn hoạt động suôn sẻ và tạo màn hình dự kiến, nhưng nó không chính xác như những gì tôi muốn.
Đầu tiên, cảm ơn vì các mã: CHỌN @cols = ISNULL (@cols + '', '') + '[' + COL_NAME + ']'
Nó là đơn giản và không thay thế dòng của tôi liên quan đến công cụ và đường dẫn xml, dường như có cùng tác dụng.
Hãy để tôi giải thích những gì tôi muốn làm.
Tôi muốn phát triển truy vấn trong Sap Business 1 (Gói kế toán - hoặc gọi nó là ERP). Sap sử dụng T-sql trong Microsoft Server 2008 và có trình tạo truy vấn riêng. Với rất ít ngoại lệ, Sap sql tương tự như T-sql.
Tôi muốn truy vấn của mình cung cấp danh sách tất cả thu nhập và chi phí theo tháng trong khoảng thời gian 12 tháng.
Tuy nhiên, tôi không muốn tiêu đề cột của tôi để được hardcoded, (vì điều này sẽ yêu cầu tôi sửa đổi truy vấn của tôi bất cứ lúc nào) như sau:
Jan-11, Feb-11, Mar- 11, Apr-11, ..... Dec-11
Thay vào đó, tôi muốn các tiêu đề cột được tạo động từ những ngày mà người dùng nhập vào màn hình nhập.
Như tôi đã đề cập, truy vấn mà tôi đăng trên diễn đàn là phiên bản đơn giản của truy vấn thực, chỉ được sử dụng để minh họa. Truy vấn thực có chứa một số biến và một màn hình đầu vào (gọi là Truy vấn - Tiêu chí lựa chọn hộp trong Sap b1) cho phép người dùng nhập một ngày. Đó là ngày này sẽ được sử dụng để xác định tên cột động.
Đây là lý do tại sao tôi cần các công cụ phức tạp như @cols, @query, trục, vv
Nếu tôi đầu vào, nói '01 .06.11' (ngày 01 tháng 6 năm 2011) trong màn hình đầu vào, ngày này sẽ được được chuyển đến sql để xác định tên của các tiêu đề cột như foll:
Jun-11, Jul-11, Aug-11 ..... May-12.
Nếu tôi đầu vào một ngày khác, nói '01 .09.10' (ngày 01 tháng chín năm 2010), các tiêu đề cột sẽ thay đổi để:
Sep-10, Oct-10, .... Aug-11
Dường như bạn đã mã hóa cứng các tiêu đề cột của tôi.
Bạn có thể xem xét lại truy vấn của mình và đề xuất thứ gì đó sẽ cho phép tên cột được tạo tham số thay vì mã hóa cứng không?
Cảm ơn
Leon Lai
Xin chào Philip, tôi đã đăng câu hỏi trả lời của bạn Cảm ơn Leon –
Đây là câu trả lời rất hay! – jTC
Sử dụng 'quotename (Col_Name)' thay vì ''[' + Col_Name + ']''. – jnm2