Microsoft Access压缩表中的多行

我有一个问题,在MS Access 2007中,我希望有人有答案。 我有一个长而简单的表格,其中包含客户名称以及每周交付的日子。 我想总结一下这个表格,把名字和所有的日子列入一个新的字段“ALLDays”,同时保留所有的数据。

源表看起来像这样:

Name Day CustomerA Monday CustomerA Thursday CustomerB Tuesday CustomerB Friday CustomerC Wednesday CustomerC Saturday 

我想有一个查询返回这样的结果:

 Name ALLDays CustomerA Monday, Thursday CustomerB Tuesday, Friday CustomerC Wednesday, Saturday 

谢谢。

通常你必须编写一个函数来允许你创build一个连接列表。 这是我用过的:

 Public Function GetList(SQL As String _ , Optional ColumnDelimeter As String = ", " _ , Optional RowDelimeter As String = vbCrLf) As String 'PURPOSE: to return a combined string from the passed query 'ARGS: ' 1. SQL is a valid Select statement ' 2. ColumnDelimiter is the character(s) that separate each column ' 3. RowDelimiter is the character(s) that separate each row 'RETURN VAL: Concatenated list 'DESIGN NOTES: 'EXAMPLE CALL: =GetList("Select Col1,Col2 From Table1 Where Table1.Key = " & OuterTable.Key) Const PROCNAME = "GetList" Const adClipString = 2 Dim oConn As ADODB.Connection Dim oRS As ADODB.Recordset Dim sResult As String On Error GoTo ProcErr Set oConn = CurrentProject.Connection Set oRS = oConn.Execute(SQL) sResult = oRS.GetString(adClipString, -1, ColumnDelimeter, RowDelimeter) If Right(sResult, Len(RowDelimeter)) = RowDelimeter Then sResult = Mid$(sResult, 1, Len(sResult) - Len(RowDelimeter)) End If GetList = sResult oRS.Close oConn.Close CleanUp: Set oRS = Nothing Set oConn = Nothing Exit Function ProcErr: ' insert error handler Resume CleanUp End Function 

Remou的版本具有添加的function,您可以传递值的数组而不是SQL语句。


示例查询可能如下所示:

 SELECT SourceTable.Name , GetList("Select Day From SourceTable As T1 Where T1.Name = """ & [SourceTable].[Name] & """","",", ") AS Expr1 FROM SourceTable GROUP BY SourceTable.Name; 

这是一个不需要VBA的简单解决scheme。 它使用更新查询将值连接到一个字段上。

我将使用我正在使用的示例来显示它。

我有一个表“emails_by_team”,它有两个字段“team_id”和“email_formatted”。 我想要的是收集一个string的给定团队的所有电子邮件。

1)我创build了一个表“team_more_info”,它有两个字段:“team_id”和“team_emails”

2)用“emails_by_team”中的所有“team_id”填充“team_more_info”

3)创build一个更新查询,将“emails_by_team”设置为NULL查询名称:team_email_collection_clear UPDATE team_more_info SET team_more_info.team_emails = Null;

4)这里有个技巧:创build一个查询更新查询名称:team_email_collection_update UPDATE team_more_info INNER JOIN emails_by_team ON team_more_info.team_id = emails_by_team.team_id SET team_more_info.team_emails = IIf(IsNull([team_emails]),[email_formatted],[team_emails ]&“;”&[email_formatted]);

5)保持信息最新创build一个macros,在需要时运行这两个查询

第一:team_email_collection_clear

第二:team_email_collection_update

QED

由于这只是一个小范围的select,另一个没有VBA的方法是build立一系列的IIF声明并连接结果。

 SELECT name, IIF(SUM(IIF(day = "Monday",1,0)) >0, "Monday, ") & IIF(SUM(IIF(day = "Tuesday",1,0)) >0, "Tuesday, ") & IIF(SUM(IIF(day = "Wednesday",1,0)) >0, "Wednesday, ") & IIF(SUM(IIF(day = "Thursday",1,0)) >0, "Thursday, ") & IIF(SUM(IIF(day = "Friday",1,0)) >0, "Friday, ") & IIF(SUM(IIF(day = "Saturday",1,0)) >0, "Saturday, ") & IIF(SUM(IIF(day = "Sunday",1,0)) >0, "Sunday, ") AS AllDays FROM Table1 GROUP BY name 

如果你是一个完美主义者,你甚至可以摆脱这样的最后一个逗号

 SELECT name, LEFT( IIF(SUM(IIF(day = "Monday",1,0)) >0, "Monday, ") & IIF(SUM(IIF(day = "Tuesday",1,0)) >0, "Tuesday, ") & IIF(SUM(IIF(day = "Wednesday",1,0)) >0, "Wednesday, ") & IIF(SUM(IIF(day = "Thursday",1,0)) >0, "Thursday, ") & IIF(SUM(IIF(day = "Friday",1,0)) >0, "Friday, ") & IIF(SUM(IIF(day = "Saturday",1,0)) >0, "Saturday, ") & IIF(SUM(IIF(day = "Sunday",1,0)) >0, "Sunday, "), LEN( IIF(SUM(IIF(day = "Monday",1,0)) >0, "Monday, ") & IIF(SUM(IIF(day = "Tuesday",1,0)) >0, "Tuesday, ") & IIF(SUM(IIF(day = "Wednesday",1,0)) >0, "Wednesday, ") & IIF(SUM(IIF(day = "Thursday",1,0)) >0, "Thursday, ") & IIF(SUM(IIF(day = "Friday",1,0)) >0, "Friday, ") & IIF(SUM(IIF(day = "Saturday",1,0)) >0, "Saturday, ") & IIF(SUM(IIF(day = "Sunday",1,0)) >0, "Sunday, ") ) - 2 ) AS AllDays FROM Table1 GROUP BY name 

您也可以考虑将它们保留在单独的列中,因为如果从另一个列表中访问此查询,这可能会更有用。 例如,仅在周二查找实例会更容易。 就像是:

 SELECT name, IIF(SUM(IIF(day = "Monday",1,0)) >0, "Monday") AS Monday, IIF(SUM(IIF(day = "Tuesday",1,0)) >0, "Tuesday") AS Tuesday, IIF(SUM(IIF(day = "Wednesday",1,0)) >0, "Wednesday") AS Wednesday, IIF(SUM(IIF(day = "Thursday",1,0)) >0, "Thursday") AS Thursday, IIF(SUM(IIF(day = "Friday",1,0)) >0, "Friday") AS Friday, IIF(SUM(IIF(day = "Saturday",1,0)) >0, "Saturday") AS Saturday, IIF(SUM(IIF(day = "Sunday",1,0)) >0, "Sunday") AS Sunday FROM Table1 GROUP BY name