Full Outer Join返回太多行

时间:2017-04-07 10:13:02

标签: sql sql-server join

我想要实现的是一个数据集,我可以根据其基准获得一组持股数据,并显示持有量是基准还是非基准。数据集应如下所示:

PositionDate   PortfolioCode   Benchmark   SecurityDesciption   PortfolioWeight   BenchmarkWeight
2017-03-31     Port1           JPM         Sec1                 1.00              1.5
2017-03-31     Port1           JPM         Sec2                 0.54              NULL
2017-03-31     Port1           JPM         Sec3                 NULL              0.5

我的SQL目前看起来像以下FULL OUTER JOIN,因此您可以根据投资组合是否持有来从投资组合数据和基准数据中返回权重:

SELECT 
        lt.PositionDate                                                         AS PositionDate
    ,   lt.PortfolioCode                                                        AS PortfolioCode
    ,   gpi.indx_desc                                                           AS Benchmark
    ,   i.iss_desc                                                              AS SecurityDescription
    ,   lt.BaseCCYEffectiveExposure / NULLIF(lt.TOTALPortfolioMV_BaseCcy,0)     AS PortfolioWeight          
    ,   issindx.WGHT_EOD                                                        AS BenchmarkWeight

FROM #Lkthru AS lt

    INNER JOIN ISSUE_DG AS i
        ON i.INSTR_ID = lt.ID_NETIK_INSTR_ID

    INNER JOIN GP_BNCHMRK_XREF AS bxref     -- Portfolio Benchmark Crossreference
        ON bxref.acct_id = lt.portfoliocode -- Links to Portfolio
        AND bxref.bnchmrk_type = 'Primary'  -- Link to reporting benchmark
        AND (@EndDate BETWEEN bxref.start_tms AND ISNULL(bxref.end_tms,@EndDate))  -- Ensures you pick up the correct benchmark for the date you are reporting for

    INNER JOIN gp_index AS gpi
        ON gpi.indx_id = bxref.indx_id      -- Links to GP_INDEX to pick up the correct benchmark

    FULL OUTER JOIN iss_indx_cnstnt AS issindx      -- Join to ensure we have all constituents of benchmark returned as well as all portfolio constituents
        ON issindx.indx_instr_id = gpi.INSTR_ID
        AND issindx.cnstnt_instr_id = i.instr_id    -- Join to constituents of portfolio
        AND issindx.as_of_dte = @EndDate

但是我没有返回所需的结果集,而且我似乎从ISS_INDX_CNSNT返回了所有记录。它必须与我的FULL OUTER JOIN上的ON后的过滤器有关,或者它不可能做我想要实现的目标?我试图避免将过滤后的数据放入临时表,然后加入或创建UNION ALL,然后再创建GROUP BY。

有没有人对我出错的地方有所了解?

编辑 - 包含工作示例

DECLARE @EndDate DATETIME

SET @EndDate = '2017-03-31'

DECLARE @Port TABLE
(
    PortCode    VARCHAR(40)
)

INSERT INTO @Port VALUES ('Port1')

DECLARE @Lkthru TABLE
(
    PositionDate    DATETIME    
,   PortfolioCode   VARCHAR(40)
,   Instr_ID        VARCHAR(40)
,   PortfolioWeight FLOAT
)

INSERT INTO @Lkthru VALUES('2017-03-31','Port1','1',1.00)
INSERT INTO @Lkthru VALUES('2017-03-31','Port1','2',0.54)

DECLARE @Issue_DG TABLE
(
    Instr_ID        VARCHAR(40)
,   SecurityDesc    VARCHAR(100)
)

INSERT INTO @Issue_DG VALUES ('1','Sec1')
INSERT INTO @Issue_DG VALUES ('2','Sec2')
INSERT INTO @Issue_DG VALUES ('3','Sec3')
INSERT INTO @Issue_DG VALUES ('4','Sec4')

DECLARE @GP_BNCHRK_XREF TABLE
(
    PortfolioCode   VARCHAR(40)
,   BenchmarkID     VARCHAR(40)
)

INSERT INTO @GP_BNCHRK_XREF VALUES ('Port1','JPM1')

DECLARE @GPIndex TABLE
(
    BenchmarkID     VARCHAR(40)
,   BenchmarkNme    VARCHAR(40)
)

INSERT INTO @GPIndex VALUES ('JPM1','JPM')

DECLARE @IssueIndexConst TABLE
(
    BenchmarkDate   DATETIME
,   BenchmarkID     VARCHAR(40)
,   Const_ID        VARCHAR(40)
,   BenchmarkWeight FLOAT
)

INSERT INTO @IssueIndexConst VALUES ('2017-03-31','JPM1','1',1.5)
INSERT INTO @IssueIndexConst VALUES ('2017-03-31','JPM1','3',0.5)
INSERT INTO @IssueIndexConst VALUES ('2017-03-31','JPM1','4',0.5)
INSERT INTO @IssueIndexConst VALUES ('2017-02-28','JPM1','1',1.5)
INSERT INTO @IssueIndexConst VALUES ('2017-02-28','JPM1','3',0.5)
INSERT INTO @IssueIndexConst VALUES ('2017-02-28','JPM1','4',0.5)

SELECT 
        ISNULL(lt.PositionDate,issindx.BenchmarkDate)   AS PositionDate
    ,   ISNULL(lt.PortfolioCode,bxref2.PortfolioCode)   AS PortfolioCode
    ,   ISNULL(gpi.BenchmarkNme,gpi2.BenchmarkNme)      AS Benchmark
    ,   ISNULL(i.SecurityDesc,ib.SecurityDesc)          AS SecurityDesc
    ,   lt.PortfolioWeight
    ,   issindx.BenchmarkWeight

FROM @GP_BNCHRK_XREF AS bxref

    INNER JOIN @Lkthru AS lt
        ON lt.PortfolioCode = bxref.PortfolioCode

    INNER JOIN @Issue_DG AS i
        ON i.Instr_ID = lt.Instr_ID

    INNER JOIN @GPIndex AS gpi
        ON gpi.BenchmarkID = bxref.BenchmarkID

    FULL OUTER JOIN @IssueIndexConst AS issindx
        ON issindx.BenchmarkID = gpi.BenchmarkID
        AND issindx.Const_ID = i.Instr_ID
        AND issindx.BenchmarkDate = @EndDate

    LEFT OUTER JOIN @Issue_DG AS ib
        ON ib.Instr_ID = issindx.Const_ID

    LEFT OUTER JOIN @GPIndex AS gpi2
        ON gpi2.BenchmarkID = issindx.BenchmarkID

    LEFT OUTER JOIN @GP_BNCHRK_XREF AS bxref2
        ON bxref2.BenchmarkID = issindx.BenchmarkID

0 个答案:

没有答案