SQL查询 - 确保()中的每个值都存在一行

时间:2010-10-12 19:38:44

标签: sql sql-server tsql sql-server-2008

目前正在努力寻找一种方法来验证2个表(有效地为表A提供大量行)

我有两张桌子

表A

 ID 
 A
 B 
 C

表格匹配

ID Number
A   1
A   2
A   9
B   1
B   9
C   2

我正在尝试编写一个SQL Server查询,它基本上会检查以确保表A中的每个值都存在一个变量值集的行(1,2,9)

上面的示例是不正确的,因为对于A中的每个记录,t应该具有匹配的每个值(1,2,9)的表中的相应记录。最终目标是:

表格匹配

ID Number
A   1
A   2
A   9
B   1
B   2
B   9
C   1
C   2
C   9

我知道它令人困惑,但一般来说,对于每个X in(某些集合),表格中应该有相应的记录匹配。我显然简化了事情。

如果您需要澄清,请告诉我。

3 个答案:

答案 0 :(得分:13)

使用:

  SELECT a.id
    FROM TABLE_A a
    JOIN TABLE_B b ON b.id = a.id
   WHERE b.number IN (1, 2, 9)
GROUP BY a.id
  HAVING COUNT(DISTINCT b.number) = 3

COUNT中的DISTINCT确保将重复项(IE:A在TABLE_B中具有值为“2”的两个记录)错误地视为正确记录。如果number列对其具有唯一或主键约束,则可以省略它。

HAVING COUNT(...) 必须 等于IN子句中提供的值的数量。

答案 1 :(得分:0)

创建所需值的临时表。如果值1,2和9位于您可以查询的某个表中,则可以动态执行此操作。

然后,SELECT FROM tempTable WHERE NOT IN (SELECT * FROM TableMatched)

答案 2 :(得分:0)

我有过一次这种情况。我的解决方案如下。

除了TableA和TableMatched之外,还有一个表定义了TableA中TableEatched中应存在的行。我们称之为TableMatchedDomain。

然后,应用程序通过控制返回行的视图访问TableMatched,如下所示:

create view TableMatchedView
select  a.ID,
        d.Number,
        m.OtherValues      
from    TableA a
        join TableMatchedDomain d
        left join TableMatched m on m.ID = a.ID and m.Number = d.Number

这样,返回的行总是正确的。如果TableMatched中缺少行,则仍会返回Numbers,但其中OtherValues为null。如果TableMatched中有额外的值,则根本不返回它们,就好像它们不存在一样。通过更改TableMatchedDomain中的行,可以非常轻松地控制此行为。如果某个值被删除了TableMatchedDomain,那么它将从视图中消失。如果将来再次添加它,那么相应的OtherValues将再次出现在之前。

我之所以这样设计它的原因是我觉得在TableMatched中建立一个行配置的不变是太脆弱了,更糟糕的是,引入了冗余。所以我从行组中删除了限制(在TableMatched中),而是使另一个表(TableMatchedDomain)的全部内容定义了正确的数据形式。