是否可以将以下内容简化为循环?
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个领域。在我开始手工编写之前,有没有办法简化过程?
答案 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