1

在 Microsoft Access 中,我想将具有相同键(=重复)的表中的特定列合并到一个新表中。

源表看起来像这样

Key Content
Apple   X
Banana  B
Banana  D
Banana  E
Banana  G
Lemon   A
Lemon   X
Orange  A

我想创建一个新表,其中每个键只有一个条目,每个键都有一个字段,该字段由累积到一个字段中的所有相应“内容”字段组成。每个“内容”值都应该用一些东西来分隔,例如:

Apple   X
Banana  B<x>D<x>E<x>G
Lemon   A<x>X
Orange  A

我更喜欢像上面那样,但如果它们位于不同的字段/列中,它也可以工作,如下所示:

Apple   X
Banana  B   D   E   G
Lemon   A   X
Orange  A

我真的很感激这方面的帮助。在谷歌上搜索时,我发现了一些第三方插件(比如这个http://www.tucows.com/preview/1586663/MS-Access-Join-Two-Tables-Software)似乎正在解决这个问题,但这肯定可以通过 MS Access 本身来完成……或者……?

4

2 回答 2

1

另一种方法是使用两列(键、内容)创建表,然后运行下面的函数将数据复制到新表中。您必须将“ExistingTableName”和“NewTableName”替换为您的表名。

Sub CreateNewTable()
    Dim rs As Recordset
    Dim rsContent As Recordset
    Dim strContent As String
    'Select and loop through all keys
    Set rs = CurrentDb.OpenRecordset("SELECT DISTINCT Key FROM [ExistingTableName]")
    Do Until rs.EOF
      'Select all content records for this key and combine into a string
      Set rsContent = CurrentDb.OpenRecordset("SELECT Content FROM [ExistingTableName] WHERE Key = " & Chr(34) & Nz(rs!Key) & Chr(34))
      strContent = ""
      Do Until rsContent.EOF
        strContent = strContent & rsContent!Content & ","
        rsContent.MoveNext
      Loop
      If Len(strContent) > 0 Then
      strContent = Mid(strContent, 1, Len(strContent) - 1)
      End If
      CurrentDb.Execute "INSERT INTO [NewTableName] (Key, Content) VALUES (" & Chr(34) & Nz(rs!Key) & Chr(34) & ", " & Chr(34) & Nz(strContent) & Chr(34) & ")"
      rs.MoveNext
    Loop

    Set rs = Nothing
    Set rsContent = Nothing
End Sub

我认为没有 VBA 就没有办法做到这一点。

看到您正在使用关系数据库,您应该考虑使用一个表来存储键和另一个表来存储内容(每行/记录一个内容),然后通过使用第三个表或通过添加“键”将它们链接起来内容表中的外键。我也将始终使用自动编号作为所有 MS Access 表中的主键,如果不是出于其他原因,这是一个好主意,只是为了避免损坏并使您能够将诸如“aple”之类的拼写错误更改为“apple”而无需打破你的关系。

于 2013-01-31T14:28:52.257 回答
1

一个版本是使用 UDF 和这个查询:

SELECT Distinct Fruit.Key, 
    ConcatADO("SELECT Content FROM Fruit WHERE Key='" & [Key] & "'","<x>","<x>") 
       AS AllRows 
INTO NewFruit
FROM Fruit

用户定义函数 (UDF)

Function ConcatADO(strSQL As String, strColDelim, strRowDelim)
   Dim rs As New ADODB.Recordset
   Dim strList As String

   On Error GoTo Proc_Err

       If strSQL <> "" Then
           rs.Open strSQL, CurrentProject.Connection
           strList = rs.GetString(, , strColDelim, strRowDelim)
           strList = Mid(strList, 1, Len(strList) - Len(strRowDelim))
       End If

       ConcatADO = strList

   Exit Function

Proc_Err:
       ConcatADO = "***" & UCase(Err.Description)
End Function

在查询设计窗口中工作,您可以创建交叉表

TRANSFORM Min(Fruit.Content) AS MinOfContent
SELECT Fruit.Key
FROM Fruit
GROUP BY Fruit.Key
PIVOT Fruit.Content;

哪个会返回

Key     A   B   D   E   G   X
Apple                       X
Banana      B   D   E   G   
Lemon   A                   X
Orange  A

然后,您可以保存交叉表并基于交叉表创建新查询。此查询可能是获取新表的 Make Table 查询,但如您所见,您有多个列。

如果每个键都有预定数量的可能行​​,还有其他方法。

最后,你必须问自己,去规范化真的是要走的路吗?

于 2013-01-31T12:10:54.913 回答