Excel:如何转置select列和组重复值? (1D到2D表)
我正在处理一个交易的数据转储,它不以特别友好的格式从任何目的系统中导出。
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和Status )是简单重复的值,以满足与每个单独请求有关的许多行数据。
Field_Name列是特定的列为每个唯一的Request_ID在单独的行上重复相同的一组值 – Value列列出了与每个Field_Name相关的对应值。
它是第3和第4列( Field_Name和Value ),我想将它们转换成行来生成如下所示的内容:
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
正如你所看到的,上面的第二个例子更合乎逻辑,而且冗余数据更less – 另外还可以进行简单的过滤和分析。
所以,我的第一个观点是试图通过将数据插入到数据透视表来实现上述操作,但是我简直无法想象逻辑。 或者,如果我能够将字段放入类似的列位置,那么值将简单地计算表格主体中的计数,而不是数值本身(数据透视表的性质)。
是否可以使用移调function? (如果是的话,我很乐意去调查自己)
有没有其他的解决办法,我没有考虑?
( 注意 – 我的数据转储中还有其他列,我没有包含在这个例子中,因为它们包含的值只是针对与单个Request_ID相关的每一行重复的值 – 所以我想我可以使用相同的逻辑来解决任何适用的解决scheme以上)
如果你能指引我正确的方向,或提供任何指导,将不胜感激,因为我难倒。
根据您的Excel版本,可以使用Power Pivot
(2010/2013)或Get & Transform
(2016)来适当地Get & Transform
数据。 你的数据,如果不在表中,将被转换成一个。
对于后者, From Table
select打开查询编辑器。 select“字段名称”和“值”列后,select“ Transform
► Pivot Column
这将popup一个Pivot Column对话框。 你想确保select如下。 你也必须selectadvanced
去到do not aggregate
选项。
select确定,你的结果与你的问题一样。 当您保存查询时,它会将结果写入新的工作表。 您需要正确格式化date列。
我不知道这将如何与700,000行。 您可能需要64位Excel。
但是,查看其他响应的一些注释,该解决scheme应该使用不同数量的Field Name / Value
对。
假设你的数据在列A:D中。 将列Request_ID复制到Col G.使用excel删除Duplicates函数以获取唯一的请求ID。 从Col H开始为所有可能的字段名称(如Name,Acc Number等)制作标题,并使用下面的公式。
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表格
我已经尝试过您发布的数据并且工作正常。 如果你想自动化整个过程,你可以尝试logging所有这些步骤的macros。
在SQL中经常需要条件聚合查询。 您的第一个示例反映了实体 – 属性 – 值模型。 要正确地alignment到不同的列,请在Field_Name列上有条件地进行聚合,返回值的最大(仅值),按重复列分组(对所有其他重复列添加SELECT
和GROUP BY
):
条件聚合查询
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
如果使用Excel for PC,则可以使用ACE SQL Engine(Windows .dll文件)在VBA中的工作簿上运行SQL查询。 如果使用Mac,将数据导入数据库(如SQLite)并在查询上运行(将CASE
语句replace为IIF()
)。 对于700,000多条logging,与内联公式或嵌套循环和数组相比,SQL可能是一个可靠的解决scheme。
以下是使用ADO(可用两个连接)的Windows解决scheme,其中数据驻留在数据选项卡中,并具有用于查询结果的空白结果选项卡。
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
或者,对于可变数量的Field_Name
,可以使用ACE SQL的唯一交叉表查询 ,这样可以避免硬编码值的可能性,例如上述聚合中的条件。 由于ACE SQL将列限制为255,下面的查询只能返回253或更less不同的Field_Name
值(2表示重复的groupby列):
交叉表查询
strSQL = " TRANSFORM Max(Value)" _ & " SELECT Request_ID, Status" _ & " FROM [DATA$]" _ & " GROUP BY Request_ID, Status" _ & " PIVOT Field_Name;"
数据
结果
select任何细胞,说G6并input:
=INDEX(A:A,(ROWS($1:1)-1)*5+2)
并抄下来。 在H6中input:
=INDEX(B:B,(ROWS($1:1)-1)*5+2)
并抄下来。 最后在I6input:
=OFFSET($D$2,COLUMNS($A:A)-1+(ROWS($1:1)-1)*5,0)
并跨越和往下复制这个单元格: