Well, lets start.
I have 4 servers with the same database. There is a query that works fine to get data from each DB individually. Its something like this:
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
Today we have one new database that merges all these 4 DBs. Each table of this new DB is a view with and Union All, with the difference that now I added a new column named "UnionAll_Empresa", to know from what server this row came from.
For example:
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;
Now I need to use that old query again, with these new "tables". The problem is that now the primary keys are not unique anymore, since there are 4 servers in the same table. So the solution would be to add the "UnionAll_Empresa" field (wich tells the name of the server) as a key along with the primary keys in the query. The new query would be something like this:
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
But it shows an error:
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
It stills find multiple results for some primary key, even when I add the comparison with the column "UnionAll_Empresa" (the name of the original server).
Am I doing something wrong?
--- Here is the full query
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)
Am I doing something Wrong?
Here's a problem in one of your join conditions:
and T4.UnionAll_Empresa = T4.UnionAll_Empresa
T4 to T4!
I really feel this question is beyond me but I'll propose something we're doing on a data warehouse project I'm working on. In addition to the standard ID primary key that we have on each table, in a number of cases we've added an additional key that we call the BK (Business Key) that we try to ensure is unique. The usage is a little different from a standard ID key because the BK is a string that has business related information embedded in it. I could see you using it to have a 'pseudo' primary key that could also tell you which server was the source for the row of data you've retrieved.
This may seem lame but it's all I could come up with.
Related
I am writing a stored procedure to retrieve purchases out of Microsoft Great Plains so they can be processed.
Great Plains has two invoice table sets of note. SOP10100/SOP10200 contain the invoice header and details of an invoice that has not yet been posted. SOP30200/SOP30300 contain the invoice header and details of invoices that have been posted. When a product is purchased, it immediately goes into SOP10100/SOP10200, and once it is posted, it is moved from SOP10100/SOP10200 to SOP30200/SOP30300. There is a common table SOP10106 that contains user-defined fields and can be joined to either table set.
When pulling purchases, we need to check both tables in case an invoice gets posted before it can be processed. Up until now, the only way we've been able to achieve this is through a UNION, which is basically two identical queries with the difference being that one joins to SOP10100/SOP10200 and the other joins to SOP30200/SOP30300.
I'm hoping to find a way that we can pare this down into a single query (utilizing the shared SOP10106 table) to hopefully get one result set that only contains the records that have either a SOP10100/SOP10200 or SOP30200/SOP30300 record. The join to the GP tables is within the OPENQUERY function.
The SPROC is below:
SELECT [Account1].AccountID, [Account1].AccountNumber AS 'Order_OrgID', [Account2].AccountNumber AS 'CI_OrgID', [Contact].cncy_CustomerNumber AS 'CustomerID', [Contact].EMailAddress1 AS 'Email', [Contact].FirstName, [Contact].LastName, [StringMapMarket].Value AS 'Market',
GP.Invoice, GP.SKU, MAP.Name, GP.OrderDate, GP.Quantity, GP.SLPRSNID, RTRIM(GP.SKU) + '-' + [StringMapMarket].Value COLLATE DATABASE_DEFAULT as AdjSku, MAP.CourseID, MAP.SubscriptionID
FROM OPENQUERY(GPSERVER, 'SELECT [SOP10100].SOPNUMBE AS Invoice, [SOP10200].ITEMNMBR AS SKU, [SOP10200].ITEMDESC AS Product, [SOP10100].CREATDDT AS OrderDate, [SOP10200].QTYORDER AS Quantity,
[SOP10100].SLPRSNID, [SOP10100].CUSTNMBR, [SOP10106].USERDEF1, [SOP10100].SOPTYPE, [SOP10100].VOIDSTTS
FROM CPI.dbo.SOP10100 WITH (NOLOCK)
INNER JOIN CPI.dbo.SOP10200 WITH (NOLOCK) ON [SOP10100].SOPNUMBE = [SOP10200].SOPNUMBE AND [SOP10100].CREATDDT > DATEADD(ww,-4,GETDATE())
INNER JOIN CPI.dbo.SOP10106 WITH (NOLOCK) ON [SOP10100].SOPNUMBE = [SOP10106].SOPNUMBE WHERE [SOP10200].SOPTYPE = 3
AND [SOP10100].VOIDSTTS <> 1
AND NOT [SOP10106].USERDEF1 = ''INTERNAL LMS''') as GP
INNER JOIN [CRMSERVER].CPI_MSCRM.dbo.Account AS [Account1] WITH(NOLOCK) ON GP.CUSTNMBR = [Account1].AccountNumber COLLATE DATABASE_DEFAULT
INNER JOIN [CRMSERVER].CPI_MSCRM.dbo.Contact WITH(NOLOCK) ON GP.USERDEF1 = [Contact].cncy_customernumber COLLATE DATABASE_DEFAULT
INNER JOIN [CRMSERVER].CPI_MSCRM.dbo.Account AS [Account2] WITH(NOLOCK) ON [Contact].ParentCustomerId = [Account2].Id
INNER JOIN CPIProcessData.dbo.StringMap AS [StringMapMarket] WITH(NOLOCK) ON [Account1].cncy_MarketType = [StringMapMarket].AttributeValue AND [StringMapMarket].AttributeName = 'cncy_MarketType' AND [StringMapMarket].ObjectTypeCode = 2
INNER JOIN CPIProcessData.dbo.StringMap AS [StringMapCountry] WITH(NOLOCK) ON [Contact].cncy_address1country = [StringMapCountry].AttributeValue AND [StringMapCountry].AttributeName = 'cncy_address1country' AND [StringMapMarket].ObjectTypeCode = 2
INNER JOIN CPIProcessData.dbo.vwLmsMapping AS MAP WITH(NOLOCK) ON MAP.Subscription = 'true' AND
CASE
WHEN [StringMapCountry].Value IN ('US','Canada') THEN RTRIM(GP.SKU) + '-' +
CASE
WHEN [StringMapMarket].Value IN ('HE','MH') THEN 'HE'
WHEN [StringMapMarket].Value IN ('ED') THEN 'ED'
ELSE 'HS'
END
ELSE RTRIM(GP.SKU)
END = map.SKU
LEFT OUTER JOIN SeatLog WITH(NOLOCK) ON GP.Invoice = [SeatLog].Invoice AND RTRIM(GP.SKU) = [SeatLog].SKU
WHERE GP.SOPTYPE = 3
AND GP.VOIDSTTS <> 1
AND NOT GP.USERDEF1 = 'INTERNAL LMS'
AND [SubscriptionLog].ID IS NULL
UNION
SELECT [Account1].AccountID, [Account1].AccountNumber AS 'Order_OrgID', [Account2].AccountNumber AS 'CI_OrgID', [Contact].cncy_CustomerNumber AS 'CustomerID', [Contact].EMailAddress1 AS 'Email', [Contact].FirstName, [Contact].LastName, [StringMapMarket].Value AS 'Market',
GP.Invoice, GP.SKU, MAP.Name, GP.OrderDate, GP.Quantity, GP.SLPRSNID, RTRIM(GP.SKU) + '-' + [StringMapMarket].Value COLLATE DATABASE_DEFAULT as AdjSku, MAP.CourseID, MAP.SubscriptionID
FROM OPENQUERY(GPSERVER, 'SELECT [SOP30200].SOPNUMBE AS Invoice, [SOP30300].ITEMNMBR AS SKU, [SOP30300].ITEMDESC AS Product, [SOP30200].CREATDDT AS OrderDate, [SOP30300].QTYORDER AS Quantity,
[SOP30200].SLPRSNID, [SOP30200].CUSTNMBR, [SOP10106].USERDEF1, [SOP30200].SOPTYPE, [SOP30200].VOIDSTTS
FROM CPI.dbo.SOP30200 WITH (NOLOCK)
INNER JOIN CPI.dbo.SOP30300 WITH (NOLOCK) ON [SOP30200].SOPNUMBE = [SOP30300].SOPNUMBE AND [SOP30200].CREATDDT > DATEADD(ww,-4,GETDATE())
INNER JOIN CPI.dbo.SOP10106 WITH (NOLOCK) ON [SOP30200].SOPNUMBE = [SOP10106].SOPNUMBE WHERE [SOP30300].SOPTYPE = 3
AND [SOP30200].VOIDSTTS <> 1
AND NOT [SOP10106].USERDEF1 = ''INTERNAL LMS''') as GP
INNER JOIN [CRMSERVER].CPI_MSCRM.dbo.Account AS [Account1] WITH(NOLOCK) ON GP.CUSTNMBR = [Account1].AccountNumber COLLATE DATABASE_DEFAULT
INNER JOIN [CRMSERVER].CPI_MSCRM.dbo.Contact WITH(NOLOCK) ON GP.USERDEF1 = [Contact].cncy_customernumber COLLATE DATABASE_DEFAULT
INNER JOIN [CRMSERVER].CPI_MSCRM.dbo.Account AS [Account2] WITH(NOLOCK) ON [Contact].ParentCustomerId = [Account2].Id
INNER JOIN CPIProcessData.dbo.StringMap AS [StringMapMarket] WITH(NOLOCK) ON [Account1].cncy_MarketType = [StringMapMarket].AttributeValue AND [StringMapMarket].AttributeName = 'cncy_MarketType' AND [StringMapMarket].ObjectTypeCode = 2
INNER JOIN CPIProcessData.dbo.StringMap AS [StringMapCountry] WITH(NOLOCK) ON [Contact].cncy_address1country = [StringMapCountry].AttributeValue AND [StringMapCountry].AttributeName = 'cncy_address1country' AND [StringMapMarket].ObjectTypeCode = 2
INNER JOIN CPIProcessData.dbo.vwLmsMapping AS MAP WITH(NOLOCK) ON MAP.Subscription = 'true' AND
CASE
WHEN [StringMapCountry].Value IN ('US','Canada') THEN RTRIM(GP.SKU) + '-' +
CASE
WHEN [StringMapMarket].Value IN ('HE','MH') THEN 'HE'
WHEN [StringMapMarket].Value IN ('ED') THEN 'ED'
ELSE 'HS'
END
ELSE RTRIM(GP.SKU)
END = map.SKU
LEFT OUTER JOIN SeatLog WITH(NOLOCK) ON GP.Invoice = [SeatLog].Invoice AND RTRIM(GP.SKU) = [SeatLog].SKU
WHERE GP.SOPTYPE = 3
AND GP.VOIDSTTS <> 1
AND NOT GP.USERDEF1 = 'INTERNAL LMS'
AND [SubscriptionLog].ID IS NULL
Does anyone know of any ideas to simplify this without having to use a UNION? I'm hoping to improve the performance.
I tried to do it a different way by using FULL JOIN and COALESCE as follows:
SELECT COALESCE(Table1.SOPNUMBE, Table2.SOPNUMBE) AS 'SOPNUMBE', COALESCE(Table1.ITEMNMBR, Table2.ITEMNMBR) AS 'SKU', COALESCE(Table1.CUSTNMBR, Table2.CUSTNMBR) AS 'Account_Number', [SubscriptionLog].ID
FROM (SELECT SOP10100.SOPNUMBE,SOP10200.ITEMNMBR,SOP10100.CUSTNMBR FROM [GPSERVER].CPI.dbo.SOP10100 INNER JOIN [GPSERVER].CPI.dbo.SOP10200 ON SOP10100.SOPNUMBE = SOP10200.SOPNUMBE) AS Table1
FULL JOIN (SELECT SOP30200.SOPNUMBE,SOP30300.ITEMNMBR,SOP30200.CUSTNMBR FROM [GPSERVER].CPI.dbo.SOP30200 INNER JOIN [GPSERVER].CPI.dbo.SOP30300 ON SOP30200.SOPNUMBE = SOP30300.SOPNUMBE) AS Table2 ON Table1.SOPNUMBE = Table2.SOPNUMBE AND Table1.ITEMNMBR = Table2.ITEMNMBR AND Table1.CUSTNMBR = Table2.CUSTNMBR
INNER JOIN [GPSERVER].CPI.dbo.SOP10106 WITH(NOLOCK) ON COALESCE(Table1.SOPNUMBE, Table2.SOPNUMBE) = SOP10106.SOPNUMBE
INNER JOIN [CRMSERVER].CPI_MSCRM.dbo.Account AS [Account1] WITH(NOLOCK) ON COALESCE(Table1.CUSTNMBR, Table2.CUSTNMBR) = [Account1].AccountNumber COLLATE DATABASE_DEFAULT
INNER JOIN [CRMSERVER].CPI_MSCRM.dbo.Contact WITH(NOLOCK) ON SOP10106.USERDEF1 = [Contact].cncy_customernumber COLLATE DATABASE_DEFAULT
--INNER JOIN [CRMSERVER].CPI_MSCRM.dbo.Account AS [Account2] WITH(NOLOCK) ON [Contact].ParentCustomerId = [Account2].Id
INNER JOIN CPIProcessData.dbo.StringMap AS [StringMapMarket] WITH(NOLOCK) ON [Account1].cncy_MarketType = [StringMapMarket].AttributeValue AND [StringMapMarket].AttributeName = 'cncy_MarketType' AND [StringMapMarket].ObjectTypeCode = 2
INNER JOIN CPIProcessData.dbo.StringMap AS [StringMapCountry] WITH(NOLOCK) ON [Contact].cncy_address1country = [StringMapCountry].AttributeValue AND [StringMapCountry].AttributeName = 'cncy_address1country' AND [StringMapMarket].ObjectTypeCode = 2
INNER JOIN CPIProcessData.dbo.vwLmsMapping AS MAP WITH(NOLOCK) ON MAP.Subscription = 'true' AND
CASE
WHEN [StringMapCountry].Value IN ('US','Canada') THEN RTRIM(COALESCE(Table1.ITEMNMBR, Table2.ITEMNMBR)) + '-' +
CASE
WHEN [StringMapMarket].Value IN ('HE','MH') THEN 'HE'
WHEN [StringMapMarket].Value IN ('ED') THEN 'ED'
ELSE 'HS'
END
ELSE RTRIM(COALESCE(Table1.ITEMNMBR, Table2.ITEMNMBR))
END = map.SKU
LEFT OUTER JOIN [SubscriptionLog] WITH(NOLOCK) ON SOP10106.SOPNUMBE = [SubscriptionLog].Invoice AND RTRIM(COALESCE(Table1.ITEMNMBR, Table2.ITEMNMBR)) = [SubscriptionLog].SKU
WHERE [SubscriptionLog].ID IS NULL
It seems to run a little better, but it returns duplicates and not the results I expect.
I had written a join query statement. that statement returns me multiple(duplicate) row again even though I'm having only single record on that.
declare #BenefitClass int ;
set #BenefitClass = (select BenefitClass From HJOB where userid='d76c5000-69e0-461e-92e1-3cfe7590d098' and CompanyId =1629)
select #BenefitClass;
select
bve.EmployerContribution,
bhsac.CatchUpValue as CatchUpValue ,
bcl.Tier,
bcl.planYear,
bhsac.Ischecked,
isnull(bhsac.Value,0) as EmployeeContribute,
Id=(convert(varchar, bcl.Id) + '$' + convert(varchar, isnull(bhsac.Id, 0))) ,
bhsac.Value ,
bhsac.HSALmitId
from
dbo.benContributionStructure bcs
inner join dbo.benVariableElection bve on bcs.PlanInfoId = bve.PlanInfoId
inner join dbo.benBenefitContributionLimit bcl on bcs.SavingCategory = bcl.CategoryID
left outer join dbo.benBenefitHSACoverage bhsac on bcs.PlanInfoId = bhsac.planInfoId
and bcl.Id=bhsac.HSALmitId --and bhsac.BenefitClassId=#BenefitClass
and bhsac.UserID='d76c5000-69e0-461e-92e1-3cfe7590d098' and bhsac.PlanInfoId=38044
left outer join dbo.benEmployeeContribution bec on bhsac.UserID = bec.UserId and bhsac.BenefitClassId = bec.BenefitClassId -- and bec.EnrollmentType !='Closed'
left outer join benOpenEnrollment oems on oems.ID = bec.OpenEnrollmentId and oems.EndDt > GETDATE()
where
bcs.PlanInfoId=38044 and bcl.Ischecked=1
and bcl.Tier !='CatchUp'
and bcl.CompanyId=1629
For that I'm getting the result as second row as duplicate :
observe the result
Try this once it may help you
declare #BenefitClass int ;
set #BenefitClass = (select BenefitClass From HJOB where userid='d76c5000-69e0-461e-92e1-3cfe7590d098' and CompanyId =1629)
select #BenefitClass;
;with cte as (
select
bve.EmployerContribution,
bhsac.CatchUpValue as CatchUpValue ,
bcl.Tier,
bcl.planYear,
bhsac.Ischecked,
isnull(bhsac.Value,0) as EmployeeContribute,
Id=(convert(varchar, bcl.Id) + '$' + convert(varchar, isnull(bhsac.Id, 0))) ,
bhsac.Value ,
bhsac.HSALmitId
from
dbo.benContributionStructure bcs
inner join dbo.benVariableElection bve on bcs.PlanInfoId = bve.PlanInfoId
inner join dbo.benBenefitContributionLimit bcl on bcs.SavingCategory = bcl.CategoryID
left outer join dbo.benBenefitHSACoverage bhsac on bcs.PlanInfoId = bhsac.planInfoId
and bcl.Id=bhsac.HSALmitId --and bhsac.BenefitClassId=#BenefitClass
and bhsac.UserID='d76c5000-69e0-461e-92e1-3cfe7590d098' and bhsac.PlanInfoId=38044
left outer join dbo.benEmployeeContribution bec on bhsac.UserID = bec.UserId and bhsac.BenefitClassId = bec.BenefitClassId -- and bec.EnrollmentType !='Closed'
left outer join benOpenEnrollment oems on oems.ID = bec.OpenEnrollmentId and oems.EndDt > GETDATE()
where
bcs.PlanInfoId=38044 and bcl.Ischecked=1
and bcl.Tier !='CatchUp'
and bcl.CompanyId=1629
)
select distinct EmployerContribution,
CatchUpValue ,Tier,planYear,Ischecked,EmployeeContribute,Id ,Value ,HSALmitId from cte
Please change your where condition as below:
select
bve.EmployerContribution,
bhsac.CatchUpValue as CatchUpValue ,
bcl.Tier,
bcl.planYear,
bhsac.Ischecked,
isnull(bhsac.Value,0) as EmployeeContribute,
Id=(convert(varchar, bcl.Id) + '$' + convert(varchar, isnull(bhsac.Id, 0))) ,
bhsac.Value ,
bhsac.HSALmitId
from
dbo.benContributionStructure bcs
inner join dbo.benVariableElection bve on bcs.PlanInfoId = bve.PlanInfoId
inner join dbo.benBenefitContributionLimit bcl on bcs.SavingCategory = bcl.CategoryID
left outer join dbo.benBenefitHSACoverage bhsac on bcs.PlanInfoId = bhsac.planInfoId
and bcl.Id=bhsac.HSALmitId --and bhsac.BenefitClassId=#BenefitClass
left outer join dbo.benEmployeeContribution bec on bhsac.UserID = bec.UserId and bhsac.BenefitClassId = bec.BenefitClassId -- and bec.EnrollmentType !='Closed'
left outer join benOpenEnrollment oems on oems.ID = bec.OpenEnrollmentId
where
bcs.PlanInfoId=38044 and bcl.Ischecked=1
and bcl.Tier !='CatchUp'
and bcl.CompanyId=1629
and bhsac.UserID='d76c5000-69e0-461e-92e1-3cfe7590d098'
and bhsac.PlanInfoId=38044
and oems.EndDt > GETDATE()
I have this SQL query below
SELECT
CASE
WHEN ISNULL(dbo.EducationalBackground.SchoolId,'') = ''
AND ISNULL(dbo.EducationalBackground.SchoolName,'') <> ''
THEN
(SELECT a.SchoolName
FROM dbo.EducationalBackground AS A
INNER JOIN dbo.PersonEducationalBackground as B ON a.EducationalBackgroundId = b.EducationalBackgroundId
WHERE b.PersonId = #PersonId AND a.EducationalLevelId = 1)
WHEN ISNULL(dbo.EducationalBackground.SchoolId,'') = ''
AND ISNULL(dbo.EducationalBackground.SchoolName,'') = ''
THEN 'N/A'
ELSE
(SELECT dbo.School.SchooldName
FROM dbo.School
INNER JOIN dbo.EducationalBackground ON dbo.School.SchoolId = dbo.EducationalBackground.SchoolId
INNER JOIN dbo.PersonEducationalBackground ON dbo.EducationalBackground.EducationalBackgroundId = dbo.PersonEducationalBackground.EducationalBackgroundId
WHERE dbo.PersonEducationalBackground.PersonId = #PersonId)
END AS SchoolName
FROM
dbo.EducationalBackground
INNER JOIN
PersonEducationalBackground ON dbo.EducationalBackground.EducationalBackgroundId = PersonEducationalBackground.EducationalBackgroundId
INNER JOIN
dbo.Person ON PersonEducationalBackground.PersonId = dbo.Person.PersonId
INNER JOIN
PIMS.Employee ON PIMS.Employee.PersonId = dbo.Person.PersonId
INNER JOIN
dbo.EducationLevel ON dbo.EducationLevel.EducationLevelId = dbo.EducationalBackground.EducationalLevelId
WHERE
dbo.Person.PersonId = #PersonId
AND dbo.EducationalBackground.EducationalLevelId = 1
I got an error above as the title said. If U use SELECT TOP 1 it is running fine but I want to get the data from that query. I have two rows of data so far.
I modified your SQL statement,It possible return different rows from your statement,Can you try it, Checking whether the result your want to get
SELECT case when ISNULL(dbo.EducationalBackground.SchoolId,'') = '' and ISNULL(dbo.EducationalBackground.SchoolName,'') <> '' then
EducationalBackground.SchoolName
WHEN ISNULL(dbo.EducationalBackground.SchoolId,'') = '' and ISNULL(dbo.EducationalBackground.SchoolName,'') = '' then 'N/A'
else School.SchooldName
end as SchoolName
FROM dbo.EducationalBackground
INNER JOIN PersonEducationalBackground on dbo.EducationalBackground.EducationalBackgroundId = PersonEducationalBackground.EducationalBackgroundId
inner JOIN dbo.Person ON PersonEducationalBackground.PersonId = dbo.Person.PersonId
inner JOIN PIMS.Employee ON PIMS.Employee.PersonId = dbo.Person.PersonId
inner JOIN dbo.EducationLevel ON dbo.EducationLevel.EducationLevelId = dbo.EducationalBackground.EducationalLevelId
LEFT JOIN PersonEducationalBackground AS b ON EducationalBackground.EducationalBackgroundId = b.EducationalBackgroundId AND EducationalBackground.EducationalLevelId=1
LEFT JOIN dbo.School ON dbo.School.SchoolId = dbo.EducationalBackground.SchoolId AND PersonEducationalBackground.PersonId = #PersonId
where dbo.Person.PersonId = #PersonId
and dbo.EducationalBackground.EducationalLevelId = 1
I have a SELECT statement that has a LEFT OUTTER JOIN that will cause a table to join to itself. The problem I am having is that when there are no results on the right side of the join the entire query retunes no results. I believe this is due to my WHERE clause but I tried to use COALESCE with NULL as the second value but that did not get any results.
Here is my SQL query:
SELECT tch1.WeekEndingDate AS WeekEndingDate,
tch1.TotalHoursWorked AS TotalHoursWorked,
e.ID AS ID,
e.FirstName AS FirstName,
e.PTORemaining AS PTORemaining,
so1.Name AS Name,
Extent5.Name AS Name1,
e.FirstName + N' ' + e.LastName AS C1,
tch2.WeekEndingDate AS WeekEndingDate1,
tch2.TotalHoursWorked AS TotalHoursWorked1
FROM dbo.TimeCardHeader AS tch1
INNER JOIN dbo.Employee AS e ON tch1.EmployeeID = e.ID
INNER JOIN dbo.StatusOption AS so1 ON tch1.CurrentStatusID = so1.ID
LEFT OUTER JOIN dbo.TimeCardHeader AS tch2 ON tch1.EmployeeID = tch2.EmployeeID
INNER JOIN dbo.StatusOption AS Extent5 ON tch2.CurrentStatusID = Extent5.ID
WHERE (tch1.WeekEndingDate = '9/24/2016' AND tch2.WeekEndingDate = '10/1/2016' AND e.ID = 80)
OR (tch1.WeekEndingDate = '9/24/2016' AND tch2.WeekEndingDate = '10/1/2016' AND e.ManagerID = 80);
For each, WeekEndingDate I tried to using WeekEndingDate = COALESCE('9/24/2016', NULL)
Is using COALESCE the correct thing to be doing and I am just using it wrong or is there another approach I should be using here so that even if there is no TimeCardHeader with a WeekEndingDate of `10/1/2016' I can get results.
From what I can see, your inner join to StatusOption is based on CurrentStatusID from TimeCardHolder (tch2) which is a left join. If there is no row in tch2, then the inner join will end up with the results you are experiencing. Is there a way you could make StatusOption join (Extent5) a left join, and combine your where with the coalesce/isnull you already tried?
COALESCE() isn't going to solve this. Right now your WHERE statement could be rewritten with no changes to:
WHERE tch1.WeekEndingDate = '9/24/2016' AND tch2.WeekEndingDate = '10/1/2016' AND (e.ID = 80 OR e.ManagerID = 80)
Which is much simpler to understand. To bring in records where tch2.WeekEndingDate is either 10/1/2016 or NULL you could just add that in this simplified version:
WHERE tch1.WeekEndingDate = '9/24/2016' AND (tch2.WeekEndingDate = '10/1/2016' OR tch2.WeekEndingDate IS NULL) AND (e.ID = 80 OR e.ManagerID = 80)
Which could also be written as:
WHERE tch1.WeekEndingDate = '9/24/2016' AND tch2.WeekEndingDate IN ('10/1/2016',NULL) AND (e.ID = 80 OR e.ManagerID = 80)
Also, as #a_horse_with_no_name mentioned in the comments, you could make your WHERE clause as:
WHERE tch1.WeekEndingDate = '9/24/2016' AND (e.ID = 80 OR e.ManagerID = 80)
And change the LEFT OUTER JOIN's ON to:
LEFT OUTER JOIN dbo.TimeCardHeader AS tch2 ON tch1.EmployeeID = tch2.EmployeeID AND tch2.WeekEndingDate = '10/01/2016'
This will drop all records from tch2 BEFORE it's joined that don't have WeekEndingDate of 10/01/2016
Move the predicates relating to tch2 into the join clause:-
SELECT tch1.WeekEndingDate AS WeekEndingDate,
tch1.TotalHoursWorked AS TotalHoursWorked,
e.ID AS ID,
e.FirstName AS FirstName,
e.PTORemaining AS PTORemaining,
so1.Name AS Name,
Extent5.Name AS Name1,
e.FirstName + N' ' + e.LastName AS C1,
tch2.WeekEndingDate AS WeekEndingDate1,
tch2.TotalHoursWorked AS TotalHoursWorked1
FROM dbo.TimeCardHeader AS tch1
INNER JOIN dbo.Employee AS e ON tch1.EmployeeID = e.ID
INNER JOIN dbo.StatusOption AS so1 ON tch1.CurrentStatusID = so1.ID
LEFT OUTER JOIN dbo.TimeCardHeader AS tch2 ON tch1.EmployeeID = tch2.EmployeeID
AND tch2.WeekEndingDate = '10/1/2016'
INNER JOIN dbo.StatusOption AS Extent5 ON tch2.CurrentStatusID = Extent5.ID
WHERE (tch1.WeekEndingDate = '9/24/2016' AND e.ID = 80)
OR (tch1.WeekEndingDate = '9/24/2016' AND e.ManagerID = 80);
If you have them in the where clause you are filtering out the joined rows altogether.
So my stored procedure has a staff column that should be generating a staff name from my Employee table. The staff name only shows up on for some of the rows. Can anyone take a look and see where my error is here:
BEGIN
IF EXISTS (SELECT 1 FROM [user] (NOLOCK)
WHERE [user].ID = #UserID
AND [user].BrandID IS NULL AND [user].SpaID IS NULL)
BEGIN
DECLARE #OrderStatusID_Completed int, #OrderStatusID_Shipped int
SET #OrderStatusID_Shipped = 4
SET #OrderStatusID_Completed = 2
SELECT
CAST('' AS varchar(50)) AS ErrMsg
, o.OrderNumber
, Customer.GUID AS CustomerGUID
, OrderItem_View.DateCreated AS ItemDate
, COALESCE(MasterProductVariant.SKU, ProductVariant.SKU, Treatment.SKU) AS SKU
, DynamicPrice.FinalPrice AS Price
--, COALESCE(MasterProductVariant.OriginalPrice, ProductVariant.OriginalPrice, Treatment.Price) AS Price
, ISNULL(Employee.FirstName,'') + ' ' + ISNULL(Employee.LastName,'') AS Staff
, COALESCE(Product.Name, Treatment.Name) AS Item
, NULL AS Note
FROM
[Order] o (Nolock)
LEFT JOIN
Customer (Nolock) ON o.CustomerID = Customer.ID
INNER JOIN
OrderItem_View (nolock) ON OrderItem_View.OrderID = o.ID
LEFT JOIN
DynamicPrice (nolock) ON OrderItem_View.DynamicPriceID = DynamicPrice.ID
LEFT JOIN
AppointmentTreatment WITH (NOLOCK) ON AppointmentTreatment.ID = OrderItem_View.AppointmentTreatmentID
LEFT JOIN
Employee (NOLOCK) ON Employee.ID = COALESCE(OrderItem_View.EmployeeID, OrderItem_View.Employee2ID, AppointmentTreatment.EmployeeID)
LEFT JOIN
Treatment_View Treatment (nolock) ON Treatment.BillableItemID = OrderItem_View.BillableItemID
LEFT JOIN
ProductVariant (NOLOCK)
LEFT JOIN
Product (NOLOCK) ON Product.ID = ProductVariant.ProductID
ON ProductVariant.BillableItemID = OrderItem_View.BillableItemID
LEFT JOIN
ProductVariant MasterProductVariant (NOLOCK) ON ProductVariant.MasterRecordID = MasterProductVariant.ID
WHERE
o.SpaID = #SpaID
AND o.IsDeleted = 0
AND o.DateCompleted >= CONVERT(DATETIME,0)
AND o.DateCompleted < GetDate()
AND o.StatusID IN (#OrderStatusID_Completed,#OrderStatusID_Shipped)
END
ELSE
SELECT CAST('Insufficient rights.' AS VARCHAR(50)) AS ErrMsg
END
It has to be in the coalesce function. Somewhere between these three - you aren't getting a value
OrderItem_View.EmployeeID
OrderItem_View.Employee2ID
AppointmentTreatment.EmployeeID
So run OrderItem_View by itself and see if there are instances where EmployeeID or Employee2ID is ever null. If so, then try to determine what employees are missing. IF there are employees missing, are they also missing in the AppointmentTreatment table? If so then therein lies the problem.