Я пишу хранимую процедуру для извлечения покупок из Microsoft Great Plains, чтобы их можно было обрабатывать.
Great Plains имеет два набора таблиц счетов-фактур.SOP10100 / SOP10200 содержит заголовок счета и детали счета, который еще не был опубликован.SOP30200 / SOP30300 содержит заголовок счета и подробности выставленных счетов.Когда продукт приобретен, он сразу переходит в SOP10100 / SOP10200, а после публикации он перемещается из SOP10100 / SOP10200 в SOP30200 / SOP30300.Существует общая таблица SOP10106, которая содержит определяемые пользователем поля и может быть присоединена к любому набору таблиц.
При извлечении покупок нам необходимо проверить обе таблицы на случай, если счет будет опубликован, прежде чем его можно будет обработать.До сих пор мы могли достичь этого только через UNION, который представляет собой два идентичных запроса, с той лишь разницей, что один присоединяется к SOP10100 / SOP10200, а другой - к SOP30200 / SOP30300.
Я надеюсь найти способ, которым мы можем свести это в один запрос (используя общую таблицу SOP10106), чтобы, надеюсь, получить один набор результатов, который содержит только записи, которые имеют либо запись SOP10100 / SOP10200, либо запись SOP30200 / SOP30300,Соединение с таблицами GP находится в функции OPENQUERY.
Ниже приведен SPROC:
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
Кто-нибудь знает какие-либо идеи по упрощению этого без использования UNION?Я надеюсь улучшить производительность.