MS Access: LEFT JOIN with Filters

时间:2015-12-14 17:53:24

标签: sql ms-access join

My MS Access version is 2003, in case that matters.

I have a single table with daily values for securities in an account. I'd like to compare the values of all securities in each account, one year ago versus today (and create an expression for the difference). The securities in the account may change over the course of a year, so there must be NULL values when linking by security. Accordingly, I'd like to perform a FULL OUTER JOIN, which I understand is not possible in MS Access. Alternatively, I'll have to create a UNION of a LEFT JOIN and RIGHT JOIN, as suggested in this SO post.

Although the below query behaves like an INNER JOIN, I believe the picture will help illustrate what I'm trying to accomplish:

enter image description here

I understand that creating this query in Design View causes the filters to go into the WHERE clause, which is filtering out data before the LEFT JOIN is performed. I'm attempting to replicate the solution proposed in this SO post, so far unsuccessfully. Following is my current SQL statement:

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#);

I've tried a few different queries, but I believe the above is most correct based on what I've gathered from SO. This causes MS Access to immediately crash. I'm expecting output something like the below (where the highlights are for SecID's no longer in the account as of 12/8/2015:

enter image description here

Any advice? Is this just a symptom of using MS Access, rather than some more robust database?

1 个答案:

答案 0 :(得分:0)

您必须在那些存在但具有NULL字段的记录和右侧(外侧)缺失的记录之间做出区别。如果您正在处理丢失的记录,则查询看起来是正确的。我不知道为什么Access崩溃。您可以将查询更改为传递查询。这意味着查询将由SQL-Server执行。当然它必须用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';