Поворот и Крест Применить - PullRequest
       41

Поворот и Крест Применить

0 голосов
/ 25 февраля 2019

Этот вопрос касается одной и той же темы, но имеет два сценария.

У меня есть набор значений, которые я извлекаю из OData.В нем есть столбец с переменными, который я хочу объединить и объединить

    create table xmpltbl
(   [Location]  nvarchar(max),
    [Site]      nvarchar(max),  
    [Variable]  nvarchar(max),  
    [Period]        datetimeoffset(3),  
    [StringValue]   nvarchar(max),
    [NumericValue] decimal(10,2)
);

INSERT INTO xmpltbl
(
    [Location],     
    [Site], 
    [Variable], 
    [Period],   
    [StringValue],
    [NumericValue]
)

VALUES 

('UK','London','Customer1','2019-01-01 00:28:53.897','Company A',NULL),
('UK','London','Product1','2019-01-01 00:28:53.897', 'Sand' ,NULL),
('UK','London','Division1','2019-01-01 00:28:53.897','Supplies',NULL),
('UK','London','Expense1','2019-01-01 00:28:53.897',NULL,150),
('UK','London','Customer2','2019-01-01 00:28:53.897','CompanyB',NULL),
('UK','London','Product2','2019-01-01 00:28:53.897','Bricks',NULL),
('UK','London','Division2','2019-01-01 00:28:53.897','Building Materials',NULL),
('UK','London','Expense2','2019-01-01 00:28:53.897',NULL,300),
('France','Paris','Customer3','2020-01-01 00:28:53.897','Company C',NULL),
('France','Paris','Product3','2020-01-01 00:28:53.897','Cement',NULL),
('France','Paris','Division3','2019-01-01 00:28:53.897','Supplies',NULL),
('France','Paris','Expense3','2019-01-01 00:28:53.897',NULL,75);

Мне нужны переменные с одинаковыми номерами, чтобы они находились в одной строке со значением рядом с ними.В идеале я хотел бы сделать это с SSIS, так как я собираю данные, используя это.

Я хочу, чтобы это выглядело так

Location    Site        Period      Customer    Product     Division        Total
UK       London     2019        CompanyA    Sand        Supplies        150
UK       London     2019        CompanyB    Bricks      Building Materials  300
France      Paris       2020        CompanyC    Cement      Supplies        75

Есть также некоторые данные, которые не соответствуют

Customer1 + Product1, Division1, Expense1

и должны быть

Customer1 + Product10, Division10, Expense10

Customer1 + Product11, Division11, Expense11

Я подумал об использовании динамического центра, так как есть около 60 из этих переменных, которые я начал работать.Однако это соединение, но я не могу сделать.Я попытался сделать CROSS APPLY, но он не вернет мне значение, даже если я положу его во временную таблицу.

DECLARE  @cols AS NVARCHAR(MAX),
         @query  AS NVARCHAR(MAX);

SET @cols = STUFF((SELECT ',' + QUOTENAME(Variable) 
            FROM xmpltbl
            GROUP BY Variable
            ORDER BY Variable
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT Location, Site, NumericValue, Period, ' + @cols + ' from 
            (
                select Location
                    , Site
                    , Variable
                    , NumericValue
                    , Period
                    , StringValue


                from xmpltbl
           ) x
            pivot 
            (
                 max(StringValue)
                for Variable in (' + @cols + ')
            ) p '

execute (@query);

1 Ответ

0 голосов
/ 11 марта 2019

Я не знаю, является ли это лучшим способом сделать это с использованием SQL, но следующее решение дает ожидаемый результат:

Импорт в временную таблицу

Я использовал следующий запрос для импорта данных во временную таблицу:

create table #xmpltbl
(   [Location]  nvarchar(max),
    [Site]      nvarchar(max),  
    [Variable]  nvarchar(max),  
    [Period]        datetimeoffset(3),  
    [StringValue]   nvarchar(max),
    [NumericValue] decimal(10,2)
);

INSERT INTO #xmpltbl
(
    [Location],     
    [Site], 
    [Variable], 
    [Period],   
    [StringValue],
    [NumericValue]
)

VALUES 

('UK','London','Customer1','2019-01-01 00:28:53.897','Company A',NULL),
('UK','London','Product1','2019-01-01 00:28:53.897', 'Sand' ,NULL),
('UK','London','Division1','2019-01-01 00:28:53.897','Supplies',NULL),
('UK','London','Expense1','2019-01-01 00:28:53.897',NULL,150),
('UK','London','Customer2','2019-01-01 00:28:53.897','CompanyB',NULL),
('UK','London','Product2','2019-01-01 00:28:53.897','Bricks',NULL),
('UK','London','Division2','2019-01-01 00:28:53.897','Building Materials',NULL),
('UK','London','Expense2','2019-01-01 00:28:53.897',NULL,300),
('France','Paris','Customer3','2020-01-01 00:28:53.897','Company C',NULL),
('France','Paris','Product3','2020-01-01 00:28:53.897','Cement',NULL),
('France','Paris','Division3','2019-01-01 00:28:53.897','Supplies',NULL),
('France','Paris','Expense3','2019-01-01 00:28:53.897',NULL,75);

Использование общих табличных выражений для получения желаемого результата

Я использовал общие табличные выражения (CTE) для построениязапрос:

WITH CTE_1 AS (SELECT *, (ROW_NUMBER() OVER(ORDER BY [Location],     
               [Site] ) - 1) / 4 as grpno FROM #xmpltbl), 
     CTE_2 AS (SELECT * , ROW_NUMBER() OVER(PARTITION BY grpno ORDER BY grpno) rn 
               FROM CTE_1),
     CTE_3 AS (SELECT *, case when rn = 2 Then 1 else 0 end as Product, case when rn = 3 Then 1 else 0 end as Supplies
               FROM CTE_2)
SELECT DISTINCT [Location], [Site], Year([Period]) as [Period], 
                FIRST_VALUE(StringValue) OVER(PARTITION BY grpno ORDER BY rn) as [Customer] ,
                FIRST_VALUE(StringValue) OVER(PARTITION BY grpno ORDER BY Product DESC) as [Product] ,
                FIRST_VALUE(StringValue) OVER(PARTITION BY grpno ORDER BY Supplies DESC) as [Supplies] ,
                MAX([NumericValue]) OVER(PARTITION BY grpno) as [Total] 
from CTE_3

Вывод

enter image description here


Примечание: это решение работает только в SQL Server2012 или более поздние версии, поскольку он использует из FIRST_VALUE() оконную функцию , которая добавлена ​​в SQL Server 2012

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...