合并行/连接行
我正在寻找与SQL Server的COALESCE函数等效的Access 2007.
在SQL Server中,我们可以执行以下操作:
人
John Steve Richard
的SQL
DECLARE @PersonList nvarchar(1024) SELECT @PersonList = COALESCE(@PersonList + ',','') + Person FROM PersonTable PRINT @PersonList
产生:约翰,史蒂夫,理查德
我想在Access 2007中做同样的事情。
有谁知道如何在Access 2007中合并这样的行?
解决方案
我认为Nz是追求,语法是Nz(variant,[if null value])
。这是文档链接:Nz函数
---Person--- John Steve Richard DECLARE @PersonList nvarchar(1024) SELECT @PersonList = Nz(@PersonList + ',','') + Person FROM PersonTable PRINT @PersonList
尽管Nz可以与COALESCE相比,但是我们不能在Access中使用它来执行我们要执行的操作。构建行值列表的不是COALESCE,而是连接到变量中。
不幸的是,在必须具有单个SQL语句且没有声明变量的工具的Access查询中,这是不可能的。
我认为我们需要创建一个函数,该函数将打开结果集,对其进行迭代,然后将行值连接为字符串。
要合并Access中的行,我们可能需要看起来像这样的代码:
Public Function Coalesce(pstrTableName As String, pstrFieldName As String) Dim rst As DAO.Recordset Dim str As String Set rst = CurrentDb.OpenRecordset(pstrTableName) Do While rst.EOF = False If Len(str) = 0 Then str = rst(pstrFieldName) Else str = str & "," & rst(pstrFieldName) End If rst.MoveNext Loop Coalesce = str End Function
我们将需要添加错误处理代码并清理记录集,如果我们使用ADO而不是DAO,这会稍有改变,但是总体思路是相同的。
我在这里了解到我们有一个表" person",其中包含3条记录。没有任何东西可以与我们在Access中描述的内容相提并论。
在"标准"访问(DAO记录集)中,我们将必须打开一个记录集并使用getrows方法获取数据
Dim rs as DAO.recordset, _ personList as String, _ personArray() as variant set rs = currentDb.open("Person") set personArray = rs.getRows(rs.recordcount) rs.close
一旦有了这个数组(它将是二维的),就可以对其进行操作以提取所需的"列"。从中提取一维数组可能是一种聪明的方法,因此我们可以使用" Join"指令将每个数组值连接到一个字符串中。
这是一个示例用户定义功能(UDF)及其可能的用法。
功能:
Function Coalsce(strSQL As String, strDelim, ParamArray NameList() As Variant) Dim db As Database Dim rs As DAO.Recordset Dim strList As String Set db = CurrentDb If strSQL <> "" Then Set rs = db.OpenRecordset(strSQL) Do While Not rs.EOF strList = strList & strDelim & rs.Fields(0) rs.MoveNext Loop strList = Mid(strList, Len(strDelim)) Else strList = Join(NameList, strDelim) End If Coalsce = strList End Function
用法:
SELECT documents.MembersOnly, Coalsce("SELECT FName From Persons WHERE Member=True",":") AS Who, Coalsce("",":","Mary","Joe","Pat?") AS Others FROM documents;
ADO版本,灵感来自onedaywhen的评论
Function ConcatADO(strSQL As String, strColDelim, strRowDelim, ParamArray NameList() As Variant) 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)) Else strList = Join(NameList, strColDelim) End If ConcatADO = strList Exit Function Proc_Err: ConcatADO = "***" & UCase(Err.Description) End Function
来自:http://wiki.lessthandot.com/index.php/Concatenate_a_List_into_a_Single_Field_%28Column%29