将包含不同数据的列转换为SQL Server

时间:2017-10-31 15:13:20

标签: sql-server excel

我有一张从excel表导入的表。我是高级SQL的新手。

第一列(帐号)按顺序包含与该列的前3行对应的帐号,帐号日期和名称。该列的下三行包含不同用户的相同类型的信息。

第二列(金额)包含金额,百分比增加,到期金额,对应于该列的下三行,依此类推。

导入当前表结构: Imported table

我想知道如何将这些值转换为具有以下结构的不同表: 帐号,帐户日期,名称,金额,百分比增加,到期金额。

预期产出表:

Expected table

我尝试过使用交叉申请,但我没有成功这样做。 我也尝试在SQL Server中使用PIVOT。但是,我遇到的示例和解决方案的列包含相同类型的数据。

SELECT [Account Number] FROM SourceTable    AS T1
PIVOT
(
    -- AGGREGATE FUNCTION
FOR
[Account Number]
    IN ( [Account Number],[Date], [Name] )
)
AS T2

请告诉我如何处理此问题。

1 个答案:

答案 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

如果可能的话,我建议更改此表结构,因为这是一个噩梦。你还有一些工作要做,因为数据类型遍布整个地方。希望这足够接近你可以完成这个。

相关问题