我正在处理一个事务数据转储,这些事务不是出于任何目的以非常友好的格式从特定系统导出的。
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相关的每一行重复 - 所以我想我可以对上面适用的任何解决方案使用相同的逻辑)
如果你可以指出我正确的方向,或提供任何指导,我将非常感激,因为我很难过。
答案 0 :(得分:3)
根据您的Excel版本,您可以使用Power Pivot
(2010/2013)或Get & Transform
(2016)来适当地转动数据。您的数据(如果尚未包含在表格中)将转换为一个数据。
对于后者,选择From Table
将打开查询编辑器。选择字段名称和值列后,选择Transform
►Pivot Column
这将打开一个Pivot Column对话框。您想确保选择如下。此外,您必须选择advanced
才能转到do not aggregate
选项。
选择确定,您的问题就会得到结果。保存查询时,它会将结果写入新工作表。您需要正确格式化日期列。
我不确定这将如何适用于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公式。
我已尝试使用您发布的数据并且工作正常。如果要自动完成整个过程,可以尝试为所有这些步骤录制宏。
答案 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
数据强>
<强>结果
答案 3 :(得分:0)