在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本身来完成...。或...?< / p>
答案 0 :(得分: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查询以获取新表,但正如您所看到的,您有多个列。
如果每个键都有预定数量的可能行,则还有其他方法。
最后,你必须问问自己,de-normalizing真的可以走了吗?
答案 1 :(得分:1)
另一种方法是使用两列(Key,Content)创建表,然后运行下面的函数将数据复制到新表中。您必须用表名替换“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,我认为没有办法做到这一点。
当您使用关系数据库时,您应该考虑使用一个表来存储密钥,使用另一个表来存储内容(每行/每个记录一个内容),然后通过使用第三个表或添加'来链接它们。 key'作为内容表中的外键。我也总是使用自动编号作为所有MS Access表中的主键,如果不是出于其他原因这是个好主意,只是为了避免损坏并使你能够将'aple'等拼写错误更改为'apple'而不用打破你的关系。