Excel:如何通过重复值转置选择列和组? (1D到2D表)

时间:2016-12-08 01:36:55

标签: excel excel-formula excel-2010 pivot-table transpose

我正在处理一个事务数据转储,这些事务不是出于任何目的以非常友好的格式从特定系统导出的。

Excel中的数据目前由大约700,000行组成,而一旦正确组织,应该只包含70,000行,其中一个特定列的唯一值转换为一些额外的列。

目前我正在使用下面这样的(简化)示例;

Request_ID   Status       Field_Name       Value
01000        Rejected     Name             John Smith
01000        Rejected     Acc Number       123456
01000        Rejected     Date             1/12/2015
01000        Rejected     Enquiry Type     Type 1
01000        Rejected     Reason           Reason 1
01001        Completed    Name             Jane Jones
01001        Completed    Acc Number       123457
01001        Completed    Date             1/12/2015
01001        Completed    Enquiry Type     Type 2
01001        Completed    Reason           Reason 2

前两列( Request_ID 状态)只是重复的值,以满足与每个单独请求相关的众多数据行。

Field_Name 列是特定列,针对每个唯一的Request_ID在各行上重复相同的值集 - 列列出与每个Field_Name相关的相应值

第3列和第4列( Field_Name )我想将其转置为行以生成如下内容:

Request_ID  Status     Name          Acc Number    Date       Enquiry Type    Reason
01000       Rejected   John Smith    123456        1/12/2012  Type 1          Reason 1
01001       Completed  Jane Jones    123457        1/12/2012  Type 2          Reason 2

如您所见,上面的第二个示例更符合逻辑,冗余数据更少 - 此外还可以进行简单的过滤和分析。

所以,我的第一个调用是尝试通过将数据插入数据透视表来实现上述操作,但我似乎无法想象逻辑。或者,如果我能够将字段放入类似的列位置,那么值将只计算表的主体中的计数,而不是值本身(就像数据透视表的性质一样)。

是否可以使用移调功能? (如果是这样,我非常乐意调查自己)

我有没有考虑过一些替代解决方案?

旁注 - 我的数据转储中还有其他列,我没有包含在示例中,因为它们包含的值只是针对与单个Request_ID相关的每一行重复 - 所以我想我可以对上面适用的任何解决方案使用相同的逻辑)

如果你可以指出我正确的方向,或提供任何指导,我将非常感激,因为我很难过。

4 个答案:

答案 0 :(得分:3)

根据您的Excel版本,您可以使用Power Pivot(2010/2013)或Get & Transform(2016)来适当地转动数据。您的数据(如果尚未包含在表格中)将转换为一个数据。

enter image description here

对于后者,选择From Table将打开查询编辑器。选择字段名称和值列后,选择TransformPivot Column

enter image description here

这将打开一个Pivot Column对话框。您想确保选择如下。此外,您必须选择advanced才能转到do not aggregate选项。

enter image description here

选择确定,您的问题就会得到结果。保存查询时,它会将结果写入新工作表。您需要正确格式化日期列。

enter image description here

我不确定这将如何适用于700,000行。您可能需要64位Excel。

但是,在查看其他回复的一些评论时,此解决方案应该适用于不同数量的Field Name / Value对。

答案 1 :(得分:2)

假设您的数据位于A:D列中。将列Request_ID复制到Col G.使用excel删除重复项功能以获取唯一的请求ID。从Col H开始为所有可能的字段名称(如名称,帐号等)创建标题,并使用以下公式。

H2 =VLOOKUP(G2,$A$2:$D$11,2,FALSE)

I2 =INDIRECT(ADDRESS(SUMPRODUCT(--($A$2:$A$11=$G2)*--($C$2:$C$11=I$1)*ROW($A$2:$A$11)),4))

拖动所有其他字段名称的I2公式。

这是Google Sheet

我已尝试使用您发布的数据并且工作正常。如果要自动完成整个过程,可以尝试为所有这些步骤录制宏。

答案 2 :(得分:2)

SQL中条件聚合查询的经典需求。您的初始示例反映了Entity-Attribute-Value模型。要正确对齐不同的列,请在 Field_Name 列上有条件地聚合,返回 Value 的max(唯一值),按重复列分组(添加到{{1} }和SELECT用于所有其他重复列):

条件聚合查询

GROUP BY

如果使用Excel for PC,则可以使用ACE SQL Engine(Windows .dll文件)在VBA中的工作簿上运行SQL查询。如果使用Mac,请将数据导入SQLite等数据库并运行以上查询(将SELECT Request_ID, Status, MAX(IIF(Field_Name='Name', Value, NULL)) AS Name, MAX(IIF(Field_Name='Acc Number', Value, NULL)) AS [Acc Number], MAX(IIF(Field_Name='Date', Value, NULL)) AS [Date], MAX(IIF(Field_Name='Enquiry Type', Value, NULL)) AS [Enquiry Type] MAX(IIF(Field_Name='Reason', Value, NULL)) AS [Reason] FROM [Worksheet$] GROUP BY Request_ID, Status 替换为CASE语句)。对于700,000多条记录,与内联公式或嵌套的IIF()循环和数组相比,SQL可能是一个强大的解决方案。

以下是使用ADO的Windows解决方案(两个可用连接),其中数据位于 DATA 选项卡中,其中包含用于查询结果的空白 RESULTS 选项卡。

for

或者,对于可变数量的Sub RunSQL() Dim conn As Object, rst As Object Dim strConnection As String, strSQL As String, i As Integer Set conn = CreateObject("ADODB.Connection") Set rst = CreateObject("ADODB.Recordset") ' CONNECTION STRINGS (DRIVER AND PROVIDER) ' strConnection = "DRIVER={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};" _ ' & ActiveWorkbook.FullName ";" strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;" _ & "Data Source='" & ActiveWorkbook.FullName & "';" _ & "Extended Properties=""Excel 8.0;HDR=YES;"";" strSQL = " SELECT Request_ID, Status," _ & " MAX(IIF(Field_Name='Name', Value, NULL)) AS Name," _ & " MAX(IIF(Field_Name='Acc Number', Value, NULL)) AS [Acc Number]," _ & " MAX(IIF(Field_Name='Date', Value, NULL)) AS [Date]," _ & " MAX(IIF(Field_Name='Enquiry Type', Value, NULL)) AS [Enquiry Type]," _ & " MAX(IIF(Field_Name='Reason', Value, NULL)) AS [Reason]" _ & " FROM [DATA$]" _ & " GROUP BY Request_ID, Status;" ' OPEN CONNECTION AND RECORDSET conn.Open strConnection rst.Open strSQL, conn ' HEADERS For i = 0 To rst.Fields.Count - 1 Worksheets("RESULTS").Cells(1, i + 1) = rst.Fields(i).Name Next i ' DATA ROWS Worksheets("RESULTS").Range("A2").CopyFromRecordset rst rst.Close: conn.Close End Sub ,您可以使用ACE SQL的唯一crosstab query,这可以避免硬编码值的可能性,例如上面聚合中的条件。并且由于ACE SQL将列限制为255,因此查询下方只能返回253个或更少的Field_Name的不同值(重复的groupby列为2):

交叉表查询

Field_Name

数据

Input Data

<强>结果

Output Data

答案 3 :(得分:0)

选择任何单元格,说 G6 并输入:

=INDEX(A:A,(ROWS($1:1)-1)*5+2)

并复制下来。在 H6 中输入:

=INDEX(B:B,(ROWS($1:1)-1)*5+2)

并复制下来。最后在 I6 中输入:

=OFFSET($D$2,COLUMNS($A:A)-1+(ROWS($1:1)-1)*5,0)

并向下和向下复制此单元格:

enter image description here