0

我需要实现一个检查 2 个表的内容的业务验证规则。该规则有 3 个部分:

  1. 如果 table1 中的所有行都与表 2 中的行匹配,那么它应该通过验证
  2. 如果 table1 中的所有行都不匹配 table2 中的行,那么它应该通过。
  3. 如果 table1 中的某些行连接到 table2 而其他行不连接,那么它应该会失败。

我在下面添加了三个数据集来显示它应该何时通过和失败

数据集 1(这应该通过):

Table1
ID   Other Column
1    xxxx
2    xxxx
3    xxxx
4    xxxx

Table2
ID    FK   OtherColumn
1     1    xxxx
2     2    xxxx
3     3    xxxx
4     4    xxxx

数据集 2(这应该通过):

Table1
ID   Other Column
1    xxxx
2    xxxx
3    xxxx
4    xxxx

Table2
ID    FK   OtherColumn
1     5    xxxx
2     6    xxxx
3     7    xxxx
4     8    xxxx

数据集 3(这应该会失败,因为 table1 中的 ID 2 和 3 与 Table2 中的任何 FK 都不匹配):

Table1
ID   Other Column
1    xxxx
2    xxxx
3    xxxx
4    xxxx

Table2
ID    FK   OtherColumn
1     1    xxxx
2     5    xxxx
3     6    xxxx
4     4    xxxx

您可以通过执行以下操作来连接这两个表:

SELECT *
FROM Table1
INNER JOIN Table2
ON Table1.ID = Table2.FK

Table2中的每条记录将有 0 或 1 条记录Table1

到目前为止,我弄清楚如何做到这一点的唯一方法是选择并比较行数:

SELECT COUNT(Table1.ID)
FROM Table1
INNER JOIN Table2
ON Table1.ID = Table2.FK

并与

SELECT COUNT(Table1.ID)
FROM Table1

我认为它有效,但感觉应该有一种更简单的方法来做到这一点。

如果有区别,数据库是 Microsoft SQL 2008

4

2 回答 2

1

你可以这样做:

SELECT count(distinct t1.id) as NumInT1, count(distinct t2.fk) as NumInT2andT1
FROM Table1 t1 left join
     Table2 t2
     ON t1.ID = t2.FK;

如果您知道Table2没有 的重复值FK,则可以将其简化为:

SELECT count(t1.id) as NumInT1, count(t2.fk) as NumInT2andT1
FROM Table1 t1 left join
     Table2 t2
     ON t1.ID = t2.FK;

NumInT2andT1当等于NumInT1或时,您测试通过0

于 2013-08-14T03:37:35.573 回答
0

这不应该失败吗?因为 ID 4 匹配,并且它是唯一匹配的

Dataset 2 (This should pass):

Table1
ID   Other Column
1    xxxx
2    xxxx
3    xxxx
4    xxxx

Table2
ID    FK   OtherColumn
1     4    xxxx
2     5    xxxx
3     6    xxxx
4     7    xxxx

好的,无论如何,您可以通过行的 COUNT 来控制它。我将制作一个可以在过程或触发器中使用的伪代码

DECLARE @matchRows int;
DECLARE @normalRows int;

SELECT @matchRows=COUNT(*)
FROM Table1 t1 JOIN Table2 t2 ON t1.id = t2.FK

SELECT @normalRows=COUNT(*)
FROM Table1 t1

IF(@matchRows>0)
BEGIN
     IF(@matchRows<@normalRows)
     BEGIN
          -Here your code in case of fail!
     END
END

你可能会做

DECLARE @booleanControl BIT;

SELECT @booleanControl = CAST(
   CASE WHEN EXISTS(SELECT *
                    FROM Table1 t1 LEFT JOIN Table2 t2 ON t1.ID = t2.KF
                    WHERE COUNT(t1.ID) = COUNT(t2.FK) OR COUNT(t2.FK) = 0
                    ) THEN 1 
                    ELSE 0 
   END 
   AS BIT)

当这个 booleanControl 返回 TRUE 时他可以通过,否则他不会

于 2013-08-14T03:49:20.533 回答