枢轴和交叉应用

时间:2019-02-25 18:56:39

标签: sql sql-server tsql ssis odata

这个问题都是围绕同一主题,但有两种情况。

我有一些要从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 :(得分:0)

我不知道这是否是使用SQL做到这一点的最佳方法,但是以下解决方案可以提供预期的结果:

导入到临时表

我使用以下查询将数据导入到临时表中:

df.loc[df['A'].isnull(),]

使用通用表表达式获取所需的输出

我使用通用表表达式(CTE)来构建查询:

df1

输出

enter image description here


侧面说明:该解决方案仅在SQL Server 2012或更高版本中有效,因为它利用了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); 窗口函数which is added in SQL Server 2012