2013-08-14 3 views
0

Мне нужно реализовать правило проверки бизнеса, которое проверяет содержимое двух таблиц. Правило состоит из 3 частей:Выберите результат, когда левое соединение присоединяется только к некоторым строкам

  1. Если все строки в table1 соответствовать строке в таблице 2, то он должен пройти проверку
  2. Если все строки в table1 не совпадают строки в table2, то он должен пройти ,
  3. Если некоторые из строк в таблице 1 присоединяются к таблице2, а другие нет, то это должно завершиться неудачно.

Я добавил три набора данных ниже, чтобы показать, когда он должен пройти и не

Dataset 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 

Dataset 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 

Dataset 3 (Это должно завершиться неудачно, поскольку ID 2 и 3 в таблице 1 не соответствуют FK в таблице 2):

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

+0

Почему вы выписываете 'one' иногда и' 1' в другое время, но никогда не выписываете 'two', только' 2' – vol7ron

+0

@ vol7ron - Теперь, когда вы упоминаете, и я останавливаюсь и думаю об этом, я, вероятно, это много времени, но я понятия не имею, почему. – Greg

ответ

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.

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 

Ok, во всяком случае, может быть, вы можете контролировать его с помощью 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, он может пройти, otherway он не делает

+0

Ваше право на набор данных 2. Извините, я заполнил тестовые данные. См. Последние изменения. Ваш псевдокод - это то, что я сейчас делаю. Я искал лучший способ сделать это. – Greg

+0

Хорошо, посмотрите, поможет ли вам новый ответ – GianlucaBobbio

Смежные вопросы