如果您构建如此庞大的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 个字段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 视图,然后粘贴复制的文本。
由于这给了您太多文本,无法从“立即”窗口复制,因此创建一个新查询 --- 任何查询都可以。然后将函数的输出分配给查询的 SQL 属性。在立即窗口中执行此操作...
CurrentDb.QueryDefs("YourQueryNameHere").SQL = BuildUnionStatement