MS Access通过所有列循环联合查询?

时间:2013-04-25 21:52:14

标签: sql vba ms-access union

是否可以将以下内容简化为循环?

SELECT ID as ColHead, "Field1" AS RowHead, Field1 AS TheVal
FROM `master`
UNION
SELECT ID, "Field2",Field2
FROM `master`
UNION
SELECT ID, "Field3",Field3
FROM `master`
UNION
...
SELECT ID, "Field90",Field90
FROM `master`

有90个领域。在我开始手工编写之前,有没有办法简化过程?

1 个答案:

答案 0 :(得分:3)

如果您构建了大量UNION查询,请考虑使用UNION ALL

UNION ALL将从每个SELECT部分返回所有行,包括重复的行。仅使用UNION,db引擎仅返回不同的行。但是,确保不同的行会对发动机造成更大的负担。

如果只需要不同的行,请使用UNION。如果您可以接受重复的行,请使用UNION ALL。当候选行不能包含重复项时,也请使用UNION ALL

如果ID字段是master主键,或者ID上有另一个唯一约束(索引),则候选行已经是唯一的。如果这是您的情况,请使用UNION ALL在数据库引擎上更轻松地进行大查询。

实际上我对尝试UNION(或UNION ALL)89 SELECTs感到担忧。我从来没有尝试过如此庞大的SQL语句。如果你想尝试,我会提供另一种方法。

我创建了一个VBA函数来创建SQL语句。它从TableDef读取字段名称并循环显示这些名称,为每个字段名称添加SELECT个字段。

这是一个立即窗口会话,我在Access 2007中测试了该功能。我的master表只包含4个字段:ID; fld1; fld2;和fld3

? BuildUnionStatement
SELECT ID as ColHead, 'fld1' AS RowHead, [fld1] AS TheVal
FROM [master]
UNION ALL
SELECT ID as ColHead, 'fld2' AS RowHead, [fld2] AS TheVal
FROM [master]
UNION ALL
SELECT ID as ColHead, 'fld3' AS RowHead, [fld3] AS TheVal
FROM [master]

创建后,我不知道您打算对查询做什么。但是创建SQL的函数提供了灵活性。您可以使用函数的输出打开记录集,将其保存为QueryDef,用于表单或报表的记录源等。

Public Function BuildUnionStatement() As String
    Const cstrTable As String = "master"
    Dim db As DAO.database
    Dim fld As DAO.Field
    Dim tdf As DAO.TableDef
    Dim strPattern As String
    Dim strSql As String

    'strPattern = vbCrLf & "UNION" & vbCrLf & 
    strPattern = vbCrLf & "UNION ALL" & vbCrLf & _
        "SELECT ID as ColHead, " & _
        "'FLDNAME' AS RowHead, " & _
        "[FLDNAME] AS TheVal" & vbCrLf & _
        "FROM [" & cstrTable & "]"

    Set db = CurrentDb
    Set tdf = db.TableDefs(cstrTable)
    For Each fld In tdf.Fields
        If fld.Name <> "ID" Then
            strSql = strSql & Replace(strPattern, _
                "FLDNAME", fld.Name)
        End If
    Next

    Set fld = Nothing
    Set tdf = Nothing
    Set db = Nothing

    'BuildUnionStatement = Mid(strSql, 10) ' UNION
    BuildUnionStatement = Mid(strSql, 14) ' UNION ALL
End Function

在模块中保存该功能后,打开立即窗口( Ctrl + g )。要执行此功能,请键入此按钮并按 Enter

? BuildUnionStatement

复制它返回的文本,创建一个新查询并切换到SQL View,然后粘贴复制的文本。

由于这给了你太多的文本要从立即窗口复制,创建一个新的查询---任何查询都可以。然后将函数的输出分配给查询的SQL属性。在立即窗口中执行此操作...

CurrentDb.QueryDefs("YourQueryNameHere").SQL = BuildUnionStatement