如何加入可能没有记录的地方

时间:2014-06-24 06:36:26

标签: sql sql-server tsql join

说我有以下架构:

create table client (clientid int)
create table mv (clientid int, fundid int, date datetime, value decimal)

insert into client values(1)
insert into mv values(1, 1, '1 may 2010', 35)
insert into mv values (1,1, '1 may 2011', 434)
insert into mv values (1, 2, '1 may 2011', 635)

第一个表代表客户,第二个表代表它们的市场价值和它们投入的资金。

我需要在2个日期显示每个基金的市场价值,但如果我找不到该日期的记录,则显示0表示日期。

这是我的尝试:

select 
c.clientid, 
mvstart.fundid startfundid,
mvend.fundid endfundid, 
mvstart.value startvalue,
mvend.value endvalue
from client c
left join mv mvstart 
on c.clientid = mvstart.clientid
and mvstart.date = '1 may 2010'
left join mv mvend 
on c.clientid = mvend.clientid 
and mvend.date = '1 may 2011'

产生:

CLIENTID    STARTFUNDID ENDFUNDID   STARTVALUE  ENDVALUE
1           1           1           35          434
1           1           2           35          635

我不明白为什么第二行的起始值为35。

我需要输出以下内容:

CLIENTID    FUNDID  STARTVALUE  ENDVALUE
1           1       35          434
1           2       0           635

任何人都可以帮我正确加入或解释为什么我的查询会产生35作为第二行的起始值吗?

继承人SQLFiddle

4 个答案:

答案 0 :(得分:2)

尝试不加入此查询:

SELECT mv.clientid,
       mv.fundid,
       MAX(CASE WHEN date = '1 may 2010' THEN value ELSE 0 END) as startvalue,
       MAX(CASE WHEN date = '1 may 2011' THEN value ELSE 0 END) as endtvalue
FROM mv
GROUP BY clientid,fundid

SQLFiddle demo

答案 1 :(得分:0)

再次记住,我现在无法访问数据库:( 此查询应该执行类似于您想要的操作

SELECT 
   X.CLIENTID,
   X.FUNDID,
   Y.STARTVAL,
   Y.ENDVAL
 FROM MV X,
   (SELECT B.CLIENTID, B.FUNDID, 
           COALESCE(A.VALUE,0) STARTVAL, 
           COALESCE(B.VALUE,0) ENDVAL FROM MV A 
    FULL OUTER JOIN MV B
    ON A.CLIENTID=B.CLIENTID AND
       A.FUNDID=B.FUNDID AND
       A.DATE='1 may 2010' AND
       B.DATE='1 may 2011'
 ) Y
  WHERE
     X.CLIENTID=Y.CLIENTID AND 
     X.FUNDID=Y.FUNDID AND 
     EXISTS (SELECT 1 FROM CLIENT C
              WHERE C.CLIENTID=X.CLIENTID)

可能你甚至不需要使用客户端表,但我添加它只是为了确保

答案 2 :(得分:0)

类似的东西:

select base.clientid, base.fundid, mvs.value, mve.value
from
    (select clientid, fundid, MIN(date) as startdate, MAX(date) as enddate from mv
     group by clientid, fundid ) base,
     mv as mvs,
     mv as mve
where base.clientid = mvs.clientid and base.fundid = mvs.fundid and base.startdate = mvs.date
      and base.clientid = mve.clientid and base.fundid = mve.fundid and base.enddate = mve.date

答案 3 :(得分:0)

我认为这会产生正确的结果:

create table #client (clientid int)
create table #mv (clientid int, fundid int, date datetime, value decimal)

insert into #client values(1)
insert into #mv values(1, 1, '1 may 2010', 35)
insert into #mv values (1,1, '1 may 2011', 434)
insert into #mv values (1, 2, '1 may 2011', 635)

select
    c.clientid, 
    mvstart.fundid startfundid,
    mvend.fundid endfundid, 
    mvstart.value startvalue,
    mvend.value endvalue
from #client c
    cross join (select distinct fundid, clientid from #mv mv) fId
    left join #mv mvstart on c.clientid = mvstart.clientid and mvstart.date = '1 may 2010' and mvstart.fundid = fId.fundid
    left join #mv mvend on c.clientid = mvend.clientid and mvend.date = '1 may 2011' and mvend.fundid = fId.fundid
where fId.clientid = c.clientid