Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 在SQL Server中将包含不同数据的列转换为多行_Sql Server_Excel - Fatal编程技术网

Sql server 在SQL Server中将包含不同数据的列转换为多行

Sql server 在SQL Server中将包含不同数据的列转换为多行,sql-server,excel,Sql Server,Excel,我有一个从excel表格导入的表格。我对高级SQL相当陌生 第一列(账号)按顺序包含对应于该列前3行的账号、账号日期和名称。该列的下3行包含不同用户的相同类型的信息 第二列(Amount)包含Amount、Percentage Increase、Amount Due,它们对应于该列的下3行,依此类推 导入的当前表结构: 我想知道如何将这些值透视到具有以下结构的不同表中: 账号、账户日期、姓名、金额、增加百分比、到期金额 预期产出表: 我尝试过使用交叉应用程序,但没有成功。 我还尝试在SQLS

我有一个从excel表格导入的表格。我对高级SQL相当陌生

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

第二列(Amount)包含Amount、Percentage Increase、Amount Due,它们对应于该列的下3行,依此类推

导入的当前表结构:

我想知道如何将这些值透视到具有以下结构的不同表中: 账号、账户日期、姓名、金额、增加百分比、到期金额

预期产出表:

我尝试过使用交叉应用程序,但没有成功。 我还尝试在SQLServer中使用PIVOT。然而,我遇到的示例和解决方案都有包含相同类型数据的列

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

请让我知道如何进行这项工作

至少可以说,这是一个非常可怕的数据结构。您有三行需要成为一行。这充其量是丑陋的。更糟糕的是,您必须至少在开始时将所有内容存储为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

如果可能的话,我建议更改这个表结构,因为这是一个噩梦。这里还有一些工作要做,因为数据类型到处都是。希望这足够接近您可以完成此操作。

至少可以说,这是一个非常糟糕的数据结构。您有三行需要成为一行。这充其量是丑陋的。更糟糕的是,您必须至少在开始时将所有内容存储为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

如果可能的话,我建议更改这个表结构,因为这是一个噩梦。这里还有一些工作要做,因为数据类型到处都是。希望这段距离足够近,您可以完成此任务。

您好,欢迎来到SO。我们需要更多的细节,因为这是相当模糊的。这是一个很好的起点。我为此道歉。我将相应地更新我的问题。谢谢。我看了一会儿你把你的样本数据作为文本而不是图像发布。那会好得多。这就是我所看到的挑战。表中没有任何指示顺序的内容,因此不知道这三行是一组逻辑信息的一部分。根据定义,表是无序集。如果您甚至包括一个标识列,您至少可以确定哪些行放在一起,尽管这相当脆弱。如果没有订购栏,这是不可能的。感谢您的快速回复。我可以在源表中包含标识列。我该怎么做?@SeanLange你能找到一个方法来回答这个问题吗?欢迎来到SO。我们需要更多的细节,因为这是相当模糊的。这是一个很好的起点。我为此道歉。我将相应地更新我的问题。谢谢。我看了一会儿你把你的样本数据作为文本而不是图像发布。那会好得多。这就是我所看到的挑战。表中没有任何指示顺序的内容,因此不知道这三行是一组逻辑信息的一部分。根据定义,表是无序集。如果您甚至包括一个标识列,您至少可以确定哪些行放在一起,尽管这相当脆弱。如果没有订购栏,这是不可能的。感谢您的快速回复。我可以在源表中包含标识列。我该怎么做?@SeanLange你能找到一个方法来回答这个问题吗?谢谢你。这很有帮助。我知道数据很难看,很难转换。我将尝试您的解决方案,并尽快更新结果。谢谢您的回答。我按照建议将它们分组,然后将账号、日期和名称的行导入到3个单独的表中。然后,我将账号插入到最后一个表中,并根据组Id更新其余字段。谢谢。这很有帮助。我知道数据很难看,很难转换。我将尝试您的解决方案,并尽快更新结果。谢谢您的回答。我按照建议将它们分组,然后将账号、日期和名称的行导入到3个单独的表中。然后,我将账号插入到最后一个表中,并根据组Id更新其余字段。