代码之家  ›  专栏  ›  技术社区  ›  Nix

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

  •  5
  • Nix  · 技术社区  · 14 年前

    目前正在努力寻找一种方法来验证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)。

    上面的示例是不正确的,因为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,表中都应该有一个匹配的对应记录。我明显简化了一些事情。

    如果你们都需要澄清,请告诉我。

    3 回复  |  直到 14 年前
        1
  •  13
  •   OMG Ponies    14 年前

    用途:

      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
    

    计数中的distinct确保重复项(即A在表B中有两个值为“2”的记录)不会被错误地视为正确的记录。如果 number 列上有唯一键约束或主键约束。

    这个 HAVING COUNT(...) 必须 等于 IN 条款。

        2
  •  0
  •   DOK    14 年前

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

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

        3
  •  0
  •   Jeffrey L Whitledge    14 年前

    我曾经遇到过这种情况。我的解决方法如下。

    除了table a和tablematched之外,还有一个表定义了table a中应该存在的行,这些行与table a中的每一行匹配。我们称之为TableMatchedDomain。

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

    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中有额外的值,那么就不会返回这些值,就好像它们不存在一样。通过更改TableMatchedDomain中的行,可以非常容易地控制此行为。如果删除了TableMatchedDomain值,则该值将从视图中消失。如果以后再将其添加回去,则相应的其他值将像以前一样再次出现。

    我这样设计它的原因是,我觉得在tablematched中的行配置上建立一个入侵性太脆弱,甚至更糟的是,引入了冗余。因此,我取消了行组(在tablematched中)的限制,而是让另一个表(tablematcheddomain)的整个内容定义数据的正确形式。