2014-12-06 75 views
0

我正在使用MS Access 2003/2007。SQL自动扩展关系

这是一个简化的场景,但希望有助于澄清。我有一个名为TableAB表由2列如下:

TableAB

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

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,这是我可以做的,但宁愿不要。任何帮助/指针将不胜感激。

回答

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的所有值是否与您的列表相匹配,并且仅与您的列表匹配。

+0

感谢您的快速响应!在HAVING SUM(IIF(FieldA in(9),1,0))末尾放置缺少的右括号,结果与我想要的非常接近,但仍然存在问题。 “In(9)”将代替用户选择。如果我用(9)替代(23,24),那么返回值是9,23,24 - 正是我想要的。但是,如果我输入(23,24,68,69),那么回报是23,24,68,69 - 它应该包括9和28. – Jim 2014-12-06 23:47:08

+0

@Jim。 。 。非常有趣的情况。如果您有多个完整的组,则原始查询将不起作用。解决方案是一个相关的子查询。我认为认为您的数据具有正确的相关性。 – 2014-12-06 23:50:14

+0

@戈登......很多人,非常感谢你在这里的帮助。 用(9)代替(1,2,10,23,68,69)我得到1,2,10,23,25,26,28,34,66,68,69 ...我想要的一切,但是10是自动扩大到包括我不想要的25,26,34,66。用户选择同时存在于字段B中的条目的自动扩展需要被限制在用户可以启用或禁用的交换机上。我现在有这个设施在最后的strSQL构建之前在其他地方工作。 – Jim 2014-12-07 00:55:56

0

随着@戈登的工作方案,我在想,我可以第一COUNT(*)后省略一切都进一步降低此给予以下,总的帮助: -

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

输出 - > 1,10,23,24,25,26,34,66,68(--->其中10自动扩展为包括25,26,34,66)

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

我们从这个(即主要问题)中遗漏的是缺少的关系关键值 - 本例中的“9”。应该包括这个值,因为所有关系项目即包括23和24

正如@戈登的解决方案(略减),我们将增加以下内容: -

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

输出 - > 9 ,并且两个部分的总输出结果恰好给了我想要的东西。

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

- >大概是这样,这里发生了什么事情,以这种方式减少戈登的解决方案是否安全?