INNER JOIN有多个表和键

时间:2012-03-30 19:53:13

标签: sql-server join union

好吧,让我们开始。

我有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。当子查询遵循=,!=,&lt;,&lt; =,&gt;,&gt; =或子查询用作表达式时,不允许这样做。

即使我使用“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 个答案:

答案 0 :(得分:3)

  

我做错了吗?

以下是您的某个加入条件中的问题:

and T4.UnionAll_Empresa   = T4.UnionAll_Empresa

T4到T4!

答案 1 :(得分:0)

我真的觉得这个问题超出了我的范围,但我会在我正在研究的数据仓库项目上提出一些建议。除了我们在每个表上使用的标准ID主键之外,在许多情况下,我们还添加了一个我们称之为BK(业务键)的附加键,我们尝试确保它是唯一的。用法与标准ID密钥略有不同,因为BK是一个嵌入了业务相关信息的字符串。我可以看到你使用它来获得一个'伪'主键,它也可以告诉你哪个服务器是你检索到的数据行的来源。

这可能看起来很蹩脚,但这是我能想到的。

相关问题