我有一张从excel表导入的表。我是高级SQL的新手。
第一列(帐号)按顺序包含与该列的前3行对应的帐号,帐号日期和名称。该列的下三行包含不同用户的相同类型的信息。
第二列(金额)包含金额,百分比增加,到期金额,对应于该列的下三行,依此类推。
我想知道如何将这些值转换为具有以下结构的不同表: 帐号,帐户日期,名称,金额,百分比增加,到期金额。
预期产出表:
我尝试过使用交叉申请,但我没有成功这样做。 我也尝试在SQL Server中使用PIVOT。但是,我遇到的示例和解决方案的列包含相同类型的数据。
SELECT [Account Number] FROM SourceTable AS T1
PIVOT
(
-- AGGREGATE FUNCTION
FOR
[Account Number]
IN ( [Account Number],[Date], [Name] )
)
AS T2
请告诉我如何处理此问题。
答案 0 :(得分:0)
至少可以说,这是一个真正可怕的数据结构。您有三行需要成为一行。这充其量是丑陋的。更糟糕的是,您必须至少在最初将所有内容存储为varchar,因为您可以分散各种数据类型。您可以在此处使用某些条件聚合。第一步是以我们可以使用的格式提供样本数据。
if OBJECT_ID('tempdb..#Something') is not null
drop table #Something
create table #Something
(
SomethingID int identity
, SomeValue varchar(50)
, SomeOtherValue int
)
insert #Something values
('1111', 10000)
, ('10/31/2017', 1)
, ('John Smith', 100)
, ('2222', 20000)
, ('10/31/2017', 1)
, ('Jane Doe', 200)
;
现在我们必须有点棘手。我把它分成了几个步骤,这样你就可以看到发生了什么。第一步是为每组三行分配一个组号。然后我们需要重新编号每个组中的每一行,以便我们知道给定行所属的组中的哪一行。这就是订购专栏如此重要的原因。然后,最后一步是使用条件聚合将此灾难解析为所需的列。
with SortedValues as
(
select *
, row_number() over(order by SomethingID) as RowNum
, case SomethingID % 3 when 1 then (SomethingID + 2) / 3
when 2 then (SomethingID + 1) / 3
when 0 then SomethingID / 3
end as GroupNumber
from #Something
)
, GroupedOrdering as
(
select *
, ROW_NUMBER() over(partition by GroupNumber order by RowNum) as GroupRowNum
from SortedValues
)
select AccountNumber = max(case when GroupRowNum = 1 then SomeValue end)
, MyDate = max(case when GroupRowNum = 2 then SomeValue end)
, AccountName = max(case when GroupRowNum = 3 then SomeValue end)
, Amount = max(case when GroupRowNum = 1 then SomeOtherValue end)
, MyPercentage = max(case when GroupRowNum = 2 then SomeOtherValue end)
, AmountDue = max(case when GroupRowNum = 3 then SomeOtherValue end)
from GroupedOrdering
group by GroupNumber
如果可能的话,我建议更改此表结构,因为这是一个噩梦。你还有一些工作要做,因为数据类型遍布整个地方。希望这足够接近你可以完成这个。