Сводка с использованием динамического запроса в SQL Server - PullRequest
0 голосов
/ 10 июня 2019

Сценарий

DECLARE @Names AS TABLE(ID INT, Name VARCHAR(MAX))

INSERT INTO @Names 
VALUES (1, 'Paul'), (2, 'John'), (3, 'Tayler');

DECLARE @PersonInfo AS TABLE 
                       (
                           ID INT,
                           NameID INT,
                           Subject VARCHAR(100),
                           Marks FLOAT
                       )

INSERT INTO @PersonInfo 
VALUES (1, 1, 'Maths', 95.34), (2, 2, 'Science', 32.12),
       (3, 3, 'History', 23.21), (4, 2, 'Maths', 32.4),
       (5, 3, 'Science', 60.34), (6, 1, 'Music', 60.23);

SELECT * FROM @PersonInfo

Я попытался сгенерировать динамические столбцы, используя выражение PIVOT, но безуспешно.Может кто-нибудь дать мне идею или решение для генерирования ниже вывод.Заранее спасибо

Ожидаемое решение:

Subject     Paul    John    Tayler
-----------------------------------
Maths       95.34   32.4    
Science             32.12   60.34
History                     23.21
Music       60.23

Ответы [ 2 ]

2 голосов
/ 10 июня 2019

Вы можете использовать динамический PIVOT для достижения результата.

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

CREATE TABLE #Names (ID INT,Name VARCHAR(MAX))
CREATE TABLE #PersonInfo (ID INT,NameID INT,Subject VARCHAR(100),Marks FLOAT)

INSERT INTO #Names VALUES (1,'Paul');
INSERT INTO #Names VALUES (2,'John');
INSERT INTO #Names VALUES (3,'Tayler');

INSERT INTO #PersonInfo VALUES (1,1,'Maths',95.34);
INSERT INTO #PersonInfo VALUES (2,2,'Science',32.12);
INSERT INTO #PersonInfo VALUES (3,3,'History',23.21);
INSERT INTO #PersonInfo VALUES (4,2,'Maths',32.4);
INSERT INTO #PersonInfo VALUES (5,3,'Science',60.34);
INSERT INTO #PersonInfo VALUES (6,1,'Music',60.23);

DECLARE @DynamicCols NVARCHAR(MAX) = '';
DECLARE @pvt NVARCHAR(MAX) = '';
DECLARE @SQLQuery NVARCHAR(MAX) = '';

SELECT @DynamicCols +=  ', SUM(' +QUOTENAME([Name])+') AS '+[Name] FROM #Names;
SET @DynamicCols = STUFF(@DynamicCols,1,1,'')
SELECT @pvt +=  ', ' +QUOTENAME([Name]) FROM #Names;
SET @pvt = STUFF(@pvt,1,1,'')

EXEC ('
SELECT [Subject],' + @DynamicCols+'
FROM (SELECT [NameID], [Subject], [Marks] FROM #PersonInfo) a
INNER JOIN #Names b ON a.NameID = b.ID
PIVOT 
(
  SUM([Marks])
  FOR [Name] IN ('+ @pvt+')
) PIV
GROUP BY [Subject]');
2 голосов
/ 10 июня 2019

Используя PIVOT, вы можете достичь ожидаемого результата:

;WITH Result AS (
   SELECT
      P.Subject, N.Name, P.Marks
   FROM @PersonInfo P
   INNER JOIN @Names N ON N.ID = P.NameID 
)
SELECT *
FROM Result
PIVOT (Max(Marks) FOR Name IN (Paul, John, Tayler)) R

Демонстрация на дб <> скрипка

...