2015-12-14 4 views
0

Моя версия MS Access - 2003, в случае, если это имеет значение.MS Access: LEFT JOIN with Filters

У меня есть таблица с ежедневными значениями ценных бумаг в учетной записи. Я бы хотел сравнить значения всех ценных бумаг в каждом аккаунте, год назад и сегодня (и создать выражение для разницы). Ценные бумаги на счете могут меняться в течение года, поэтому при связывании по безопасности должно быть значение NULL. Соответственно, я хотел бы выполнить команду FULL OUTER JOIN, которая, как я понимаю, невозможна в MS Access. В качестве альтернативы, мне нужно будет создать UNIONLEFT JOIN и RIGHT JOIN, as suggested in this SO post.

Хотя ниже запрос ведет себя как INNER JOIN, я считаю, что картина поможет проиллюстрировать то, что я пытается выполнить:

enter image description here

Я понимаю, что создание этого запроса в режиме конструктора приводит к тому, фильтры, чтобы перейти в пункт WHERE, который отфильтровывает данные до выполнения LEFT JOIN. Я пытаюсь воспроизвести предлагаемое решение in this SO post, пока безуспешно. Ниже мой текущий оператор SQL:

SELECT dbo_vw_Core_Monitor_Historical.AsOFdate, 
    dbo_vw_Core_Monitor_Historical.Account, 
    dbo_vw_Core_Monitor_Historical.SecID, 
    dbo_vw_Core_Monitor_Historical.YTM, 
    dbo_vw_Core_Monitor_Historical_1.AsOFdate, 
    dbo_vw_Core_Monitor_Historical_1.Account, 
    dbo_vw_Core_Monitor_Historical_1.SecID, 
    dbo_vw_Core_Monitor_Historical_1.YTM, 
    [dbo_vw_Core_Monitor_Historical_1.YTM] - [dbo_vw_Core_Monitor_Historical.YTM] AS YTM_Change 

FROM dbo_vw_Core_Monitor_Historical 

LEFT JOIN 
    dbo_vw_Core_Monitor_Historical AS dbo_vw_Core_Monitor_Historical_1 
ON ((dbo_vw_Core_Monitor_Historical.Account = dbo_vw_Core_Monitor_Historical_1.Account) 
    AND (dbo_vw_Core_Monitor_Historical.SecID = dbo_vw_Core_Monitor_Historical_1.SecID) 
    AND ((dbo_vw_Core_Monitor_Historical_1.AsOFdate)=#12/8/2015#)) 

WHERE ((dbo_vw_Core_Monitor_Historical.AsOFdate)=#12/8/2014#); 

Я пробовал несколько различных запросов, но я считаю, что выше, наиболее правильным на основе того, что я собрал из SO. Это приводит к немедленному сбою доступа MS Access. Я ожидаю выход что-то вроде ниже (где основные моменты для SecID уже не в счете на 12/8/2015?:

enter image description here

Любые советы Является ли это просто симптом использования MS Access , а не более надежную базу данных?

+0

Вы уверены, что у вас будут точные даты на один год? Если нет, вам нужно будет иметь «DateDiff» между двумя ближайшими датами до 1 года друг от друга и использовать это в своих формулах (формулах). Возможно, вам нужно несколько запросов - один выбирает текущие даты, другой выбирает «год назад», затем присоединяется к двум и создает ваши формулы? –

+0

@ WayneG.Dunn На самом деле даты, о которых я беспокоюсь, являются переменными. Я просто произвольно предоставил даты, которые примерно на 1 год отличаются от иллюстративных целей. –

+0

Я понимаю образцы дат, однако вы упоминаете возможные «нулевые» ценные бумаги, вызванные изменениями в холдингах. Было бы лучше понять, как вы хотите иметь дело с безопасностью, которая может не иметь точной даты 1 год назад (или сегодняшней даты). Например, если у вас есть цена за безопасность от 363 дней назад (а это на 50%!), Вам все равно, если она исключена из вашего запроса? Вы можете использовать «IF» для проверки нулей и замены на «» –

ответ

0

Вы должны сделать разницу между записями, которые есть, но с полями NULL и записями, отсутствующими на правой (внешней) стороне. Если вы имеете дело с отсутствующими записями, ваш запрос выглядит Я понятия не имею, почему Access сбой. Вы можете изменить запрос на сквозной запрос. Это означает, что запрос будет выполняться SQL-сервером. Конечно, он должен быть написан в T-SQL, тогда:

SELECT 
    A.AsOFdate, 
    A.Account, 
    A.SecID, 
    A.YTM, 
    B.AsOFdate, 
    B.Account, 
    B.SecID, 
    B.YTM, 
    B.YTM - A.YTM AS YTM_Change 
FROM 
    dbo.vw_Core_Monitor_Historical A 
    LEFT JOIN dbo.vw_Core_Monitor_Historical AS B 
     ON A.Account = B.Account AND 
      A.SecID = B.SecID AND 
      B.AsOFdate = '2015/12/08' 
WHERE 
    A.AsOFdate = '2014/12/08';