本质上,我们有时(?)需要提供对表格的引用,即使我不需要它。例如。 查询输入必须包含至少一个表或查询
我的问题是为什么查询 q1
SELECT 1
执行得很好,并给我 1 行 1 列结果表,其中 1 作为值,但查询 q2 SELECT * FROM q1
会产生上述错误?
当我将 q1 更改为
SELECT 1 from dummy_table
(其中 dummy_table 是具有虚拟值的虚拟表)时,q2 运行良好。
为什么 q1 的内部结构与 q2 有任何关系? q1 本身就可以正常工作。 q2 是否“展开”q1 然后编译一条语句
SELECT * FROM (SELECT 1)
(它本身会产生相同的错误)。我可以以某种方式强制 Access 不窥视父母的内部结构吗?
另外为什么 SELECT * FROM (SELECT 1)
给出错误而 SELECT 1
工作正常?
当“裸”
FROM
单独使用而不是作为另一个查询的一部分时,Access将仅接受没有SELECT
子句的查询。
正如您所发现的,当
SELECT 1
是整个语句时,它是有效的。 但是 Access 会抱怨 “查询输入必须至少包含一个表或查询” 如果您尝试在另一个查询中使用该“裸”SELECT
,例如 SELECT q.* FROM (SELECT 1) AS q;
同样,虽然
SELECT 1
和 SELECT 2
单独使用时都有效,但尝试 UNION
它们会触发相同的错误:
SELECT 1
UNION ALL
SELECT 2
没有办法避免这个错误。 正如您还发现的那样,将“裸”
SELECT
保存为命名查询,然后在另一个查询中使用命名查询仍然会触发错误。 这只是 Access 数据库引擎的限制,我使用过的每个 Access 版本(>= Access 2000)都是如此。
今天,当我们尝试使用
UNION
查询向查询结果添加一些记录时,遇到了此问题,错误为 3067。
这不起作用:
SELECT
UserID, UserName
FROM USERS
UNION SELECT
0, 'Add User...'
但正如原始问题中所指出的,如果您使用有效的表名称,则可以解决该问题。
只需调整代码即可从任何表中选择单个记录 (
TOP 1
)。这里我使用 MSysObjects
因为它应该始终存在并有记录。
SELECT
UserID, UserName
FROM USERS
UNION SELECT TOP 1
0, 'Add User...'
FROM MSysObjects
即使我们在技术上没有使用“虚拟”表中的任何数据,它也满足联合查询的编译器要求并返回所需的结果。
要获取不相关值的列表,例如填充下拉列表,您需要 (SELECT [值] + FROM [任何表]) 的并集,如以下示例所示:
SELECT * FROM (SELECT FORMAT(DateAdd("m",-8,Date()),"yyyy_mm") AS periode FROM MSysObjects)
UNION (SELECT FORMAT(DateAdd("m",-7,Date()),"yyyy_mm") AS periode FROM MSysObjects)
UNION (SELECT FORMAT(DateAdd("m",-6,Date()),"yyyy_mm") AS periode FROM MSysObjects)
UNION (SELECT FORMAT(DateAdd("m",-5,Date()),"yyyy_mm") AS periode FROM MSysObjects)
UNION (SELECT FORMAT(DateAdd("m",-4,Date()),"yyyy_mm") AS periode FROM MSysObjects)
UNION (SELECT FORMAT(DateAdd("m",-3,Date()),"yyyy_mm") AS periode FROM MSysObjects)
UNION (SELECT FORMAT(DateAdd("m",-2,Date()),"yyyy_mm") AS periode FROM MSysObjects)
UNION (SELECT FORMAT(DateAdd("m",-1,Date()),"yyyy_mm") AS periode FROM MSysObjects)
UNION (SELECT FORMAT(DateAdd("m",0,Date()),"yyyy_mm") AS periode FROM MSysObjects)
UNION (SELECT FORMAT(DateAdd("m",1,Date()),"yyyy_mm") AS periode FROM MSysObjects)
UNION (SELECT FORMAT(DateAdd("m",2,Date()),"yyyy_mm") AS periode FROM MSysObjects)
UNION (SELECT FORMAT(DateAdd("m",3,Date()),"yyyy_mm") AS periode FROM MSysObjects)
UNION (SELECT FORMAT(DateAdd("m",4,Date()),"yyyy_mm") AS periode FROM MSysObjects)
UNION (SELECT FORMAT(DateAdd("m",5,Date()),"yyyy_mm") AS periode FROM MSysObjects)
UNION (SELECT FORMAT(DateAdd("m",6,Date()),"yyyy_mm") AS periode FROM MSysObjects)
UNION (SELECT FORMAT(DateAdd("m",7,Date()),"yyyy_mm") AS periode FROM MSysObjects)
UNION (SELECT FORMAT(DateAdd("m",8,Date()),"yyyy_mm") AS periode FROM MSysObjects)
此处的值采用月份格式,从过去 8 个月到未来 8 个月。遗憾的是,这是最优雅的方式。