0

我有两张桌子。小部件,其中包含有关每个小部件的信息(颜色、大小等);每个小部件都有一个唯一的 ID,WidgetID。
另一个表是测试,它包含有关在每个小部件上运行的多个测试的信息。因此,该表对于每个 WidgetID 都有多行。它包含我们可以调用的信息(WidgetID、Date、Param1、Param2 等);测试信息。
我编写了一个查询,为每个 WidgetID 按日期查找最近的两个测试。SQL 如下所示:

SELECT Widgets.WidgetID, Widgets.Color, Widgets.Size, T.Date, T.Param1, T.Param2,*
FROM Tests AS T INNER JOIN Widgets ON T.WidgetID=Widgets.WidgetID
WHERE (((Select COUNT(*)从测试
WHERE WidgetID = T.WidgetID AND Date > T.Date)) < 2 );

这很好用。但是,它给了我太多的小部件。我创建了一个过滤名为 WidgetFilter 的小部件的查询。它基本上只是根据我选择的内容来选择我想要的。我的想法是我将运行相同的查询,将上面代码中的“Widgets”替换为“WidgetFilter”。但是,当我这样做时,它需要永远。事实上,它只是冻结。我把它放了一个半小时,它就坐在那里,我不得不 alt ctl delete。我唯一的想法是它正在为每一行测试查询 WidgetFilter 查询(那是很多行)。我还尝试在原始查询中应用过滤条件。我得到相同的结果。

有一个更好的方法吗?一个查询可以完成所有操作,甚至可能看起来不像这样,或者我在想应该有一种方法可以运行一次 WidgetFilter 查询并使该数据看起来像一个表一样访问(不存在这样的事情临时表)。这样它就不会为测试中的每个项目运行 WidgetFilter。

编辑:
WidgetFilter 实际上非常复杂。我创建了这些 GUI 选择表,用户可以在其中看到两列。左侧的选项和他/她正在创建的列表在右侧,中间有一个添加按钮和一个删除按钮。然后他们调用执行 WidgetFilter 的报告,yadda yadda yadda。无论如何,当用户添加一个项目时,它会将该项目添加到一个表中。因此对于 Widget 类别 Color,会有一个名为 ColorList 的表。用户通过 gui 构建此列表。其中有三种 gui(颜色、大小、类型)。对于它们中的每一个,都有一个表格,然后有一个全局布尔值(例如,ColorFlag),它告诉使用哪个过滤器(颜色、大小或类型)。
因此,在 WidgetFilter 查询中,Color 下的条件框将具有以下内容:
在(从 ColorList 中选择颜色)
中,有一个表达式列 Expr1: getColorFlag(),它是一个返回全局变量 ColorFlag 值的模块。在应用颜色表的同时也是如此。因此,总而言之,有三行标准。代码如下所示:

选择 Widgets.WidgetID, Widgets.Color, Widgets.Size, Widgets.Type
From Widgets
WHERE (getColorFlag() = True AND (Widgets.Color) In(Select Color FROM ColorList))
OR (getSizeFlag() = True AND (Widgets. Size) In(Select Size FROM SizeList))
OR (getTypeFlag() = True AND (Widgets.Type) In(Select Type FROM TypeList))

4

3 回答 3

1

你可能不知道的一件事。我相信如果您有一个为任何行返回 NULL 值的子选择,大多数版本的 Access(不知道 2007 年)都会陷入困境。因此,如果任何这些表中的颜色、大小或类型为 NULL,就会导致您看到的症状。

于 2009-10-13T00:02:14.077 回答
0

行。这就是我最终做的事情。我通过 VBA 代码创建了一个临时表,如下所示:

Function createWidgetFilterTemp()
Dim mySQL
Dim deleteSQL
deleteSQL = "DELETE * FROM TempWidgetFilter"
mySQL = "SELECT * INTO TempWidgetFilter FROM WidgetFilter" DoCmd.SetWarnings False
DoCmd.RunSQL deleteSQL
DoCmd.RunSQL mySQL
DoCmd.SetWarnings True
End Function

我在一个名为 WidgetCombo 的查询中加入了 TempWidgetFilter 和测试。这使我可以访问所有测试信息和仅针对我感兴趣的 WidgetID 的所有 Widget 信息。我尝试使用 Select Count(*) 语句执行相同的查询,但我遇到了与 Access 冻结相同的问题. 因此,我随后使用如下代码通过 VBA 创建了另一个临时表:

Function createWidgetTemp()
Dim mySQL
Dim deleteSQL
deleteSQL = "DELETE * FROM TempWidgetCombo"
mySQL = "SELECT * INTO TempWidgetCombo FROM WidgetCombo" DoCmd.SetWarnings False
DoCmd.RunSQL deleteSQL
DoCmd.RunSQL mySQL
DoCmd.SetWarnings True
End Function

每当我从表单中调用查询时,我都会运行这两个函数。这有效!实际上,它工作得相当快。我认为如果没有第一个临时表它会工作,但是将它作为一个临时表而不仅仅是一个查询使我的应用程序的另一部分运行得更快,所以我离开了它。顺便说一句,我必须在删除行注释掉的情况下运行一次,这样它才能创建表。我想我可能已经能够手动创建表格,但是这样它以正确的方式获得了所有字段。感谢您的帮助,我希望这对将来寻求临时表帮助的其他人有所帮助。

于 2009-10-13T16:00:43.237 回答
0

很简单,真的。

SELECT TOP 2 Widgets.WidgetID, Widgets.Color, Widgets.Size, T.Date, T.Param1, T.Param2,*
FROM Tests AS T INNER JOIN Widgets ON T.WidgetID=Widgets.WidgetID
ORDER BY T.Date DESC
于 2012-06-01T07:20:49.287 回答