Как мне обрабатывать длинные сравнения в SQL - PullRequest
0 голосов
/ 18 февраля 2009

У меня патологическая проблема с SQL, поэтому я обычно разбираю все проблемы с базами данных, создавая быстрые программные приложения для решения моих проблем с SQL.

(как и в этом случае)

Благодаря StackOverflow я думаю, что я могу быть посрамлен на правильность, поэтому я хотел бы узнать, как сделать этот вид устранения неполадок SQL в реальном SQL или самом T-SQL (если это возможно):

У меня есть:

база данных DB1 Таблица A (номер единицы, номер здания)

база данных DB2 Таблица B (номер единицы, номер здания)

  1. Я хочу предложить единицы (номера единиц), существующие в таблице A из базы данных DB1, которые не существуют в таблице B из базы данных DB2 и наоборот.

  2. Может быть более одного юнита с одинаковым номером юнита, это произойдет, потому что один и тот же номер юнита может быть дан юнитам разных зданий.

  3. У меня нет доступа на запись ни к одной из баз данных.

Я надеюсь, что это не рассматривается как пост "дай мне кодз", я хотел бы знать, как люди с большим беглым знанием SQL, чем я, сортируют этот вид алгоритма, сообщения в учебные пособия или подсказки более чем приветствуются, нет полной код требуется, но если это помогает разобраться, пожалуйста, сделайте.

Сначала я подумал, что могу просто получить все номера юнитов из одной таблицы и исключить их из выбора из другой, например:

select concated.unit from 
( SELECT (  unitNo + ',' + CONVERT(varchar(12), BuildingNo) ) as unit
FROM A) concated 
having concated.unit not in

(
'201,1',
'202,1',
'203,1',
'204,1',
'205,1',
'206,1',
[...]

Обычно это работает, но количество единиц в любой таблице огромно, при попытке этого SQL-сервер завершается с:

"не хватило места в стеке"

Спасибо

Ric

Ответы [ 2 ]

3 голосов
/ 18 февраля 2009

Я думаю, вы ищете полное внешнее соединение. Что дает вам номера единиц, которые вы просили в части 1.

Select 
   A.UnitNumber, B.UnitNumber
from
   DB1.dbo.TableA A FULL OUTER JOIN DB2.dbo.TableB B 
       on A.UnitNumber = B.UnitNumber
       and A.BuildingNumber = B.BuildingNumber
Where
   A.UnitNumber is null or B.UnitNumber is null

Другие вопросы, которые могут представлять интерес, я изложил ниже.

Это дает вам записи в A, а не в B.

Select
    A.UnitNumber
From
    DB1.dbo.TableA A Left Join DB2.dbo.TableB B 
        on A.UnitNumber = B.UnitNumber 
        and A.BuildingNumber = B.BuildingNumber
Where
    B.UnitNumber is null

И вы просто переворачиваете его, чтобы найти записи в B, которых нет в A.

Select
    B.UnitNumber
From
    DB2.dbo.TableB B left join DB1.dbo.TableA A 
        on B.UnitNumber = A.UnitNumber
        and B.BuildingNumber = A.BuildingNumber
Where
    A.UnitNumber is null
2 голосов
/ 18 февраля 2009

Как сказал JPunyon, но если вы хотите, чтобы они все были в одном списке, то что-то вроде:

Select 
    [UnitNumber] = COALESCE(A.UnitNumber, B.UnitNumber),
    [Source] = CASE WHEN A.UnitNumber IS NOT NULL THEN 'A' ELSE 'B' END
from
    DB1.dbo.TableA A
    FULL OUTER JOIN DB2.dbo.TableB B 
        on A.UnitNumber = B.UnitNumber
Where
    A.UnitNumber is null or B.UnitNumber is null
ORDER BY COALESCE(A.UnitNumber, B.UnitNumber)
...