2015-12-14 7 views
1

Долгосрочный lurker здесь с моим первым вопросом.MS SQL SERVER 2008 RS OUTER APPLY и пустой RS

У меня есть следующие таблицы:

  • Accounts
  • Письмо
  • номер телефоны

Я хочу, чтобы захватить все от счетов и для каждого Счета записи, самые последних Top 1 от сообщений электронной почты и PhoneNumbers, где Accounts.ID = Emails.AcctID или Accounts.ID = PhoneNumbers.AcctID.

Мои РС в настоящее время: SELECT, АССТ * со счетов AS АССТ OUTER APPLY (SELECT TOP 1 E. * FROM письма как E WHERE E.E_AcctID = ACCT.ACCT_ID ORDER BY E.E_ID DESC) ЭМ OUTER APPLY (. SELECT TOP 1 PH. * FROM PhoneNumbers AS PH WHERE PH.PH_AcctID = ACCT.ACCT_ID ORDER BY PH_ID DESC) PH WHERE ACCT.ACCT_Status> 2;

Проблема в том, что не каждая учетная запись имеет соответствующую запись в электронных письмах или PhoneNumbers.

Итак, некоторые из APPLY RS возвращаются пустым, а затем я получаю эту ошибку RS: ADODB.Recordset error '800a0cc1' Элемент не может быть найден в коллекции, соответствующей запрашиваемому имени или порядку.

Любая идея, как я могу работать с пустыми наборами записей?

Большое спасибо заранее. Cheers, Noah

+1

1) тег используется СУБД (я предполагаю, что это должен быть sql-сервером) 2) разместить некоторые данные примера 3) опубликовать вашу попытку до сих пор –

+0

Как сказал @vkp, больше данных было бы полезно. С учетом сказанного, по моему опыту присоединение к оконной функции быстрее, чем внешняя, и должно просто возвращать значения null. –

+0

Спасибо за отзыв! Обновит ваши предложения. Cheers, N – nbardach

ответ

0

Проблема решена!

Я заменил «ACCT. *» В начале RS с помощью «*», и это сделало трюк. Я непреднамеренно исключил другие таблицы!

Спасибо всем, кто посмотрел и прокомментировал!

0

Если предположить, что у вас есть столбец created_datetime в каждой таблице, чтобы указать самую последнюю строку можно использовать функцию RowNumber, чтобы сделать работу увидеть эту Exemple

declare @ACCOUNTS table (ID_ACC int) 
declare @EMAILS table (EMAIL VARCHAR(50), ID_ACC int, CREATED_DATETIME DATETIME) 
declare @PHONES table (PHONE VARCHAR(50), ID_ACC int, CREATED_DATETIME DATETIME) 


insert into @ACCOUNTS 
SELECT '1' ID_ACC 
UNION ALL 
SELECT '2' ID_ACC 
UNION ALL 
SELECT '3' ID_ACC 

INSERT INTO @EMAILS 
SELECT '[email protected]' EMAIL,'1' ID_ACC, '2015-12-14 22:00:00' CREATED_DATETIME 
UNION ALL 
SELECT '[email protected]' EMAIL,'1' ID_ACC, '2015-12-14 22:53:00' 
UNION ALL 
SELECT '[email protected]' EMAIL,'3' ID_ACC, '2015-12-14 22:54:00' 
UNION ALL 
SELECT '[email protected]' EMAIL,'3' ID_ACC, '2015-12-14 22:55:30' 


INSERT INTO @PHONES 
SELECT '00213555555' PHONE,'1' ID_ACC, '2015-12-14 22:10:00' CREATED_DATETIME 
UNION ALL 
SELECT '00213554444' PHONES,'2' ID_ACC, '2015-12-14 22:54:00' 
UNION ALL 
SELECT '00213556666' PHONES,'3' ID_ACC, '2015-12-14 22:54:00' 
UNION ALL 
SELECT '00213557777' PHONES,'3' ID_ACC, '2015-12-14 23:10:00' 

SELECT 
* 
FROM 
(SELECT 
ROW_NUMBER() over (partition by A.ID_ACC order by E.CREATED_DATETIME DESC,P.CREATED_DATETIME DESC) AS ROW_ORDER, 
A.ID_ACC, 
E.EMAIL, 
P.PHONE 
FROM @ACCOUNTS as A 
left join @EMAILS as E 
on A.ID_ACC=E.ID_ACC 
left join @PHONES as P 
on A.ID_ACC=P.ID_ACC) AS TAB 
WHERE TAB.ROW_ORDER=1 
Смежные вопросы