SQL自动扩展关系

时间:2014-12-06 22:58:17

标签: sql ms-access-2007 ms-access-2003

我正在使用MS Access 2003/2007。

这是一个简化的方案,但希望有助于澄清。我有一个名为TableAB的表,由2列组成,如下所示:

TableAB

FieldA用于填充UserForm多选列表框,然后允许用户选择一个或多个要搜索的项。然后,使用所选项目搜索包含数千条记录的单独主表。

FieldB描述FieldA中某些项目之间的4个关系集(9,10,19和28),并允许我们自动展开搜索选择,如果单独的“自动”用户切换已启用。

例如,如果所选搜索项为2,10和11,则自动扩展搜索将为2,10,11,25,26,34,66。这里有25,26,34和66自动包含在内。

我可以使用以上示例自动展开以下内容:

SELECT FieldA    
FROM TableAB    
WHERE FieldA In (2,10,11) Or FieldB In (2,10,11);

我的问题:

如果用户选择了特定关系的所有项目但没有选择描述该关系的主要项目(FieldB中的项目),那么,我希望自动包含该项目(没有用户切换是因为应该总是包括丢失的项目所需要的。

例如,如果用户选择23和24,那么我希望包括9 - 但仅提供用户输入23和24

我可以使用以下示例返回主要关系项:

SELECT DISTINCT FieldB   
FROM tblABC         
WHERE  (FieldA In (1,2,9,30,68) And FieldB <> Null) Or FieldB In(1,2,9,30,68);

但是由于我的SQL知识有限,我发现很难想到一种简单/优雅地实现我的目标的方法,而不需要过多地使用Visual Basic进行交互,这是我可以做但却不愿意做的事情。任何帮助/指针将不胜感激。

2 个答案:

答案 0 :(得分:1)

我认为以下查询可以满足您的需求:

SELECT FieldA    
FROM TableAB    
WHERE FieldA In (9) Or FieldB In (9)
UNION
SELECT FieldB
FROM TableAB as ab
GROUP BY FieldB
HAVING SUM(IIF(FieldA in (9), 1, 0)) = COUNT(*) AND
       COUNT(*) = (SELECT COUNT(*) FROM TableAB WHERE FieldA in (9) AND ab.FieldB = TableAB.FieldB)

第二个select添加了更高级别的关系。 having子句会检查给定FieldB的所有值是否与您的列表匹配,并且仅匹配到您的列表。

答案 1 :(得分:0)

在@ Gordon的工作解决方案的帮助下,我想我可以通过省略第一个COUNT(*)之后的所有内容来进一步减少这一点,总计: -

SELECT FieldA    
FROM TableAB    
WHERE FieldA In (1,10,23,24,68) Or FieldB In (1,10,23,24,68)

输出 - &gt; 1,10,23,24,25,26,34,66,68(---&gt;其中10自动扩展到包括25,26,34,66)

Or FieldB In (1,10,23,24,68)取决于用户切换,允许用户使用匹配的字段B项作为关系链接自动展开到完整集合。 UserForm代码将根据需要插入此可选段。

我们在此缺失的内容(即主要问题)是此示例中缺少的关系键值 - “9”。应包括此值,因为包括所有关系项,即23和24。

与@ Gordon的解决方案(稍微减少)一样,我们将添加以下内容: -

UNION
SELECT FieldB
FROM TableAB
GROUP BY FieldB
HAVING SUM(IIF(FieldA In (1,10,23,24,68), 1, 0)) = COUNT(*);

输出 - &gt; 9,两半的总输出组合给了我我想要的东西。

现在,如果我正确解码,由于我们是GROUPING BY FieldB,然后SUM(IIF(FieldA In (1,10,23,24,68), 1, 0))计算每个项目的匹配FieldB命中总数。然后,对于每个相应的FieldB项,= COUNT(*)返回完全匹配的总数(即,该集合的所有关系项都存在)。 HAVING将返回的数据集限制为仅满足完全匹配条件的数据集。

- &gt;这是粗略的,这里发生了什么,以这种方式减少戈登的解决方案是否安全?