2015-09-17 3 views
0

Я использую SQL Server 2012 & У меня есть две таблицы.с использованием точки, где изменяется количество столбцов

tblStocks      tblFunds 

fundCode nvarchar    fundCode nvarchar 
stockID nvarchar    fundType nvarchar 
shares int 

Я покажу пример данных ниже, прежде чем объяснить, как его, вероятно, легче увидеть пример первой.

tblStocks 
fundCode stockID shares 
abcd  m33  20 
abcd  b22  10 
abcd  c33  5 
abcd  p99  6 
xyzu  m33  10 
xyzu  b22  8 
xyzu  w88  12 

tblFunds 
fundCode fundType 
abcd  EQ 
xyzu  EQ 

Так что, пожалуйста, обратите внимание, что средства в tblStocks могут иметь многочисленные акции, но каждый из них будет уникален тем, что фонд, т.е. ABCD не будет держать два M33 акции.

Также обратите внимание, что abcd и xyzu могут хранить одинаковые запасы, поэтому оба могут удерживать m33.

Ниже приводится результат, который я хотел бы видеть. Поэтому у меня есть уникальный список акций, а затем для каждого фонда у меня есть количество акций, принадлежащих этому фонду. Поэтому я знаю, что мне нужно использовать стержень здесь (ну его единственный способ, который я знаю). Однако добавленное осложнение (для меня) - это количество разных фондов, которые не всегда будут равными двум, поэтому я не знаю, как это кодировать в sql-сервере?

stockID abcd xyzu 
m33  20  10 
b22  10  8 
c33  5  0 
p99  6  0 
w88  0  12 
+1

Вам нужно использовать динамический SQL, когда вы не знаете столбцы вывода. –

+1

Возможный дубликат [SQL Server dynamic PIVOT query?] (Http://stackoverflow.com/questions/10404348/sql-server-dynamic-pivot-query) – Kritner

+0

Извините, что я новичок в sql. Я не понимаю, что вы подразумеваете под использование динамического SQL. Я в голове, я думал, что могу сделать отдельный запрос на tblFunds, чтобы получить список средств, а затем использовать этот список в своём стержне? – mHelpMe

ответ

3

Для создания сводной инструкции необходимо использовать динамический SQL.

Что-то вроде:

DECLARE @SQL varchar(MAX) 
DECLARE @columns varchar(MAX) 

SET @columns = 'column1, column2, column3' -- etc. 

SET @SQL = 'SELECT * FROM() PIVOT (
' + @columns + ' 
)' 

EXECUTE(@SQL) 

Так вы хотите, чтобы получить столбцы (убедитесь, что нет NULL значения)

DECLARE @columns varchar(MAX) 


SELECT @columns = COALESCE(@columns + ', ', '') + QUOTENAME(fundCode) 
FROM tblFunds 
WHERE fundCode IS NOT NULL 

PRINT @columns 

И затем выполнить запрос следующим образом:

DECLARE @SQL nvarchar(MAX) 
DECLARE @columns nvarchar(MAX) 
DECLARE @columnsOrder nvarchar(MAX) 


SELECT @columns = COALESCE(@columns + N', ', N'') + QUOTENAME(fundCode) 
FROM tblFunds 


SELECT @columnsOrder = COALESCE(@columnsOrder + N', ', N'') + QUOTENAME(fundCode) + N' DESC' 
FROM tblFunds 


SET @SQL = N' 
SELECT * FROM 
(
    SELECT 
     stockid 
     ,fundCode 
     ,shares 
    FROM tblStocks 
) AS dataToPivot 
PIVOT 
(
    SUM(shares) 
    FOR fundCode IN (' + @columns + N') 
) AS p 

ORDER BY ' + @columnsOrder + N' 
' 


-- PRINT @columns 
-- PRINT @columnsOrder 
-- PRINT @SQL 
EXECUTE(@SQL) 

Вы должны по-прежнему улавливать случай отсутствия записей в tblFunds (в ​​самом начале запрос будет работать нормально, но не возвращает никаких значений и не пустой таблицы либо) ...

Я также хотел бы создать еще 2 записи тестов, один с апострофом, другая с квадратными скобками []

INSERT INTO tblFunds (fundCode, fundType) VALUES (N'ACME [US]', N'EQ'); 
INSERT INTO tblFunds (fundCode, fundType) VALUES (N'Goa''uld Charity Fund', N'EQ'); 

и вы Посмотрите, как он работает отлично, когда вы запускаете QUOTENAME на имена столбцов.

Смежные вопросы