Sql 旋转和交叉应用
这个问题围绕着同一个主题,但有两个场景 我从OData那里得到了一组值。它有一个列,其中包含一些变量,我希望将这些变量透视并连接在一起Sql 旋转和交叉应用,sql,sql-server,tsql,ssis,odata,Sql,Sql Server,Tsql,Ssis,Odata,这个问题围绕着同一个主题,但有两个场景 我从OData那里得到了一组值。它有一个列,其中包含一些变量,我希望将这些变量透视并连接在一起 create table xmpltbl ( [Location] nvarchar(max), [Site] nvarchar(max), [Variable] nvarchar(max), [Period] datetimeoffset(3), [StringValue]
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提取数据时使用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个变量是我需要处理的。然而,这是加入,但我不能这样做。 我试图进行交叉应用,但即使我将其放入临时表中,它也不会返回值
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);
我不知道这是否是使用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
输出
旁注:此解决方案仅适用于SQL Server 2012或更高版本,因为它使用from
FIRST\u VALUE()
window函数“但是它是连接,但我不能执行。”什么连接?你的问题只有一张桌子。请向我们显示您的动态数据透视查询以及结果的错误。是的,有一个表,可能应该使用“选定”一词,而不是“联接”。因此,它就像上面的Customer1+Product1,Division1,Expense1那样结束。在这种情况下,我不太清楚你能做什么,不能做什么。同样,如果你想发布你的代码,以及结果出了什么问题,这将是很清楚的。我编辑了这篇文章,并将我的动态查询放在这里。查询没有问题,我只是不知道如何将结果输入到位置站点周期客户产品部门总计我认为使用子查询或CTE比使用dynamic pivot更容易,你得到了一个很好的答案。你试过吗??