INNER JOIN с несколькими таблицами и ключами - PullRequest
3 голосов
/ 30 марта 2012

Хорошо, начнем.

У меня 4 сервера с одной и той же базой данных.Есть запрос, который отлично работает, чтобы получить данные из каждой БД в отдельности.Это примерно так:

SELECT "blablablablabla"
FROM  [UNION_ALL_BASES]..OVPM T01 with (nolock)
INNER JOIN [UNION_ALL_BASES]..VPM2 T11 with (nolock) ON T01.UnionAll_Empresa = T11.UnionAll_Empresa and T01.DocEntry = T11.DocNum
INNER JOIN [UNION_ALL_BASES]..PCH6 T2 with (nolock) ON T11.UnionAll_Empresa = T2.UnionAll_Empresa and T11.DocEntry = T2.DocEntry and T11.InstId = T2.InstlmntID
INNER JOIN [UNION_ALL_BASES]..OPCH T3 with (nolock) ON T2.UnionAll_Empresa  = T3.UnionAll_Empresa and T2.DocEntry  = T3.DocEntry
INNER JOIN [UNION_ALL_BASES]..PCH1 T3a with (nolock) ON T3.UnionAll_Empresa = T3a.UnionAll_Empresa and T3.DocEntry = T3a.DocEntry
LEFT JOIN [UNION_ALL_BASES]..OOCR T3b with (nolock) ON T3a.UnionAll_Empresa = T3b.UnionAll_Empresa and T3a.OcrCode2 = T3b.OcrCode
INNER JOIN [UNION_ALL_BASES]..OSLP T4 with (nolock) ON T4.UnionAll_Empresa   = T4.UnionAll_Empresa and T3.SlpCode   = T4.SlpCode  
and  T11.InvType = ''18''
AND T01.Canceled <> ''Y''
AND T01.CashSum > 0

Сегодня у нас есть одна новая база данных, которая объединяет все эти 4 БД.Каждая таблица этой новой БД представляет собой представление и Union All, с той разницей, что теперь я добавил новый столбец с именем «UnionAll_Empresa», чтобы узнать, с какого сервера пришла эта строка.

Например:

CREATE VIEW AACP as
SELECT 'G8Networks Solucoes' as UnionAll_Empresa, * from SBO_G8NETWORKS_SOLUCOES.dbo.AACP
UNION All
SELECT 'G8Networks NIC' as UnionAll_Empresa, * from SBO_G8NETWORKS_NIC.dbo.AACP
UNION All
SELECT 'SPIN' as UnionAll_Empresa, * from SBO_SPIN.dbo.AACP
UNION All
SELECT 'FA2R' as UnionAll_Empresa, * from SBO_FA2R.dbo.AACP;

Теперь мне нужно снова использовать этот старый запрос с этими новыми "таблицами".Проблема в том, что теперь первичные ключи больше не являются уникальными, поскольку в одной таблице находятся 4 сервера.Таким образом, решение было бы добавить поле «UnionAll_Empresa» (которое сообщает имя сервера) в качестве ключа вместе с первичными ключами в запросе.Новый запрос будет выглядеть примерно так:

SELECT "blalalalalala"
FROM  [UNION_ALL_BASES]..OVPM T01 with (nolock)
INNER JOIN [UNION_ALL_BASES]..VPM2 T11 with (nolock) ON T01.DocEntry = T11.DocNum and T01.UnionAll_Empresa = T11.UnionAll_Empresa
INNER JOIN [UNION_ALL_BASES]..PCH6 T2 with (nolock) ON  T11.DocEntry = T2.DocEntry and T11.InstId = T2.InstlmntID and T11.UnionAll_Empresa = T2.UnionAll_Empresa
INNER JOIN [UNION_ALL_BASES]..OPCH T3 with (nolock) ON  T2.DocEntry  = T3.DocEntry and T2.UnionAll_Empresa  = T3.UnionAll_Empresa
INNER JOIN [UNION_ALL_BASES]..PCH1 T3a with (nolock) ON T3.DocEntry = T3a.DocEntry and T3.UnionAll_Empresa = T3a.UnionAll_Empresa
LEFT JOIN [UNION_ALL_BASES]..OOCR T3b with (nolock) ON  T3a.OcrCode2 = T3b.OcrCode and T3a.UnionAll_Empresa = T3b.UnionAll_Empresa
INNER JOIN [UNION_ALL_BASES]..OSLP T4 with (nolock) ON  T3.SlpCode   = T4.SlpCode and T4.UnionAll_Empresa   = T4.UnionAll_Empresa
WHERE T11.InvType = ''18''
AND T01.Canceled <> ''Y''
AND T01.CashSum > 0

Но он показывает ошибку:

Подзапрос вернул более 1 значения.Это недопустимо, если подзапрос следует =,! =, <, <=,>,> = Или когда подзапрос используется в качестве выражения.

Он все еще находит несколько результатов для некоторого первичного ключа, даже когда я добавляю сравнение со столбцом «UnionAll_Empresa» (имя исходного сервера).

Я что-то не так делаю?

--- Вот полный запрос

set @vQuery = '
SELECT   --Pagametos de NF em dinheiro 
T01.UnionAll_Empresa,
Base = ''' + @database + ''', 
NomeEmp = (select a.CompnyName from [UNION_ALL_BASES]..OADM a with (nolock)),
CNPJ = (select a.TaxIdNum from [UNION_ALL_BASES]..oadm a with (nolock)),
IE = (Select TaxIdNum2 from [UNION_ALL_BASES]..OADM with (nolock)),
Filial = (Select PrintHeadr from [UNION_ALL_BASES]..OADM with (nolock)),
Proj = isnull(T3.Project,''''),
OcrCode2 = isnull(T3a.OcrCode2,''0''),
OcrName = isnull(T3b.OcrName,''Sem projeto definido''),
''NF'' TipoDoc,
''DIN'' Tipo,
T01.CardCode, 
T01.CardName,
CardFName = (select CardFName from [UNION_ALL_BASES]..OCRD with (nolock) where OCRD.CardCode = T01.CardCode and OCRD.UnionAll_Empresa = T01.UnionAll_Empresa),
T01.DocEntry CodigoBaixaPagamento,
T11.DocEntry NumeroSapDocumento,
T01.DocDate DataDocBaixa,
T3.DocDate,
T11.InstId Parcela,
'''' SituacaoParc,
''1900-01-01'' DataUltBaixa,
T11.InvType,
T2.InsTotal ValorDaParcelaOriginal,
T01.DocDate DataLancamentoBaixa,
T2.DueDate VencimentoOriginalParcela,
T3.SeqCode,
SerieNF = (select SeqName from [UNION_ALL_BASES]..NFN1 with (nolock) where SeqCode = T3.SeqCode and UnionAll_Empresa = T3.UnionAll_Empresa),
T3.Series,
T3.Serial,
T3.SlpCode,
T4.SlpName,
round((T3a.LineTotal/T3.DocTotal)*(T11.SumApplied/T01.DocTotal)*(T01.CashSum),2) ValorPago,
T01.DocTotal TotalBaixa,
T01.CashSum TotalDinBaixa,
T01.TrsfrSum TotalTransfBaixa,
T01.[CheckSum] TotalCHBaixa,
T01.BoeSum TotalBoeBaixa,
T01.CreditSum TotalCCredBaixa,
Case 
When T01.CashSum   > 0 Then ''Dinheiro''
When T01.TrsFrSum  > 0 Then ''Transferência''
When T01.CreditSum > 0 Then ''Cartao''
End TipoDocumento,
'''' NossoNumBol,
'''' DigNossoNumBol,
''1900-01-01'' VencBoleto,
'''' CodBancoBol,
'''' NomeBancoBol,
0 VlrTotBol,
'''' NomeFPagtoBol,
'''' LinhaDigBol,
'''' TrsfrRef,
'''' NumCH,
'''' DataCH,
'''' StatusCH,
0 VlrTotCH,
'''' BancoCH,
'''' AgenciaCH,
'''' ContaCH,
'''' BoeStatus,
'''' CodCCred,
'''' NomeCCred,
'''' NumComprCartao,
0 NumParcCartao,
''1900-01-01'' PrimVencimentoCartao,
0 VlrTotCartao,
VlrDin = round((T3a.LineTotal/T3.DocTotal)*(T11.SumApplied/T01.DocTotal) * T01.CashSum,2),
VlrTransf = 0,
VlrCredit = 0,
VlrBol = 0,
VlrCH = 0,
VlrCart = 0,
VlrDev = 0,
VlrBLI = 0
FROM  [UNION_ALL_BASES]..OVPM T01 with (nolock)
INNER JOIN [UNION_ALL_BASES]..VPM2 T11 with (nolock) ON T01.DocEntry = T11.DocNum and T01.UnionAll_Empresa = T11.UnionAll_Empresa
INNER JOIN [UNION_ALL_BASES]..PCH6 T2 with (nolock) ON  T11.DocEntry = T2.DocEntry and T11.InstId = T2.InstlmntID and T11.UnionAll_Empresa = T2.UnionAll_Empresa
INNER JOIN [UNION_ALL_BASES]..OPCH T3 with (nolock) ON  T2.DocEntry  = T3.DocEntry and T2.UnionAll_Empresa  = T3.UnionAll_Empresa
INNER JOIN [UNION_ALL_BASES]..PCH1 T3a with (nolock) ON T3.DocEntry = T3a.DocEntry and T3.UnionAll_Empresa = T3a.UnionAll_Empresa
LEFT JOIN [UNION_ALL_BASES]..OOCR T3b with (nolock) ON  T3a.OcrCode2 = T3b.OcrCode and T3a.UnionAll_Empresa = T3b.UnionAll_Empresa
INNER JOIN [UNION_ALL_BASES]..OSLP T4 with (nolock) ON  T3.SlpCode   = T4.SlpCode and T4.UnionAll_Empresa   = T4.UnionAll_Empresa
WHERE T11.InvType = ''18''
AND T01.Canceled <> ''Y''
AND T01.CashSum > 0
'
exec ('insert into #RelContasPagar ' + @vQuery)

Ответы [ 2 ]

3 голосов
/ 31 марта 2012

Я что-то не так делаю?

Вот проблема в одном из ваших условий соединения:

and T4.UnionAll_Empresa   = T4.UnionAll_Empresa

Т4 до Т4!

0 голосов
/ 31 марта 2012

Я действительно чувствую, что этот вопрос мне не подходит, но я предложу кое-что, что мы делаем в проекте хранилища данных, над которым я работаю.В дополнение к стандартному первичному ключу ID, который имеется у нас в каждой таблице, в ряде случаев мы добавляли дополнительный ключ, который мы называем BK (бизнес-ключ), который мы стремимся обеспечить уникальным.Использование немного отличается от стандартного ключа ID, потому что BK - это строка, в которую встроена информация, связанная с бизнесом.Я мог видеть, как вы используете его, чтобы иметь «псевдо» первичный ключ, который мог бы также сказать вам, какой сервер был источником для строки данных, которую вы получили.с.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...