2

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

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个字段。在我开始手写之前,有没有办法简化这个过程?

4

1 回答 1

3

如果您构建如此庞大的UNION查询,请考虑UNION ALL改用。

UNION ALL将返回每个部分的所有SELECT,包括重复的行。使用 just UNION,数据库引擎仅返回不同的行。然而,确保不同的行会给引擎带来更大的负担。

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

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

实际上,我很担心尝试UNION(或UNION ALL) 89 SELECTs。我从未尝试过如此庞大的 SQL 语句。如果你想尝试,我会提供另一种方法。

我创建了一个 VBA 函数来创建 SQL 语句。它从 中读取字段名称,TableDef并遍历这些名称SELECT以为每个字段名称添加一个片段。

这是一个即时窗口会话,我在 Access 2007 中测试了该功能。我的master表仅包含 4 个字段IDfld1; 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 视图,然后粘贴复制的文本。

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

CurrentDb.QueryDefs("YourQueryNameHere").SQL = BuildUnionStatement
于 2013-04-26T15:06:11.430 回答