当“ with”子句没有数据时,将“ with”子句结果与表连接

时间:2019-01-24 18:49:51

标签: sql sql-server

我正在处理一个带有with子句(视图)的查询,该查询使用INNER / OUTER连接与一个表连接。问题是当表没有数据时,联接失败,并且不返回任何结果。但是,视图中有数据。

我使用了INNER联接,在第一种情况下失败。然后,我尝试了“左外连接”,这同样行不通。实际上,主要查询非常复杂,因此我在下面的代码片段中提出了问题。我只希望这种格式的答案

with myView as (Select mp.Id, sum(mp.Quantity) counts from Map mp where 
mp.bizDate='22-Jan-2019' group by mp.Id)

Select m.Id, mv.counts, (mv.counts - sum(m.Quantity)) from Map m 
LEFT OUTER JOIN myView mv ON 
m.id=mv.Id where m.bizDate='25-Jan-2019' group by m.Id, mv.counts

问题是,当Map表没有记录时,即使myView有记录,它也不返回任何数据。无论如何,如果其中之一包含数据(myView或Map),我都需要记录。

样本数据:

表:地图

Id          Quantity               BizDate
A            100                   22-Jan-2019
A            300                   22-Jan-2019
A            300                   25-Jan-2019
B            100                   22-Jan-2019
B            200                   25-Jan-2019
C            500                   22-Jan-2019
D            300                   25-Jan-2019

预期输出应为:

Id        Counts               (counts-Quantity)
A         400                       100         --> (400-300)
B         100                      -100         --> (100-200)
C         500                       500         --> (500-NA)
D         0                        -300         --> (NA-300)

3 个答案:

答案 0 :(得分:1)

如果您希望始终检索数据,请使用FULL OUTER JOIN

with myView as (Select t.tuneId, t.name from Tune t where <someCondition>)

Select m.name, mv.name from Map m 
FULL OUTER JOIN myView mv ON 
m.id=mv.tuneID where <someCondition> 

答案 1 :(得分:1)

使用条件汇总来计算每个期望日期的数据。

SQL DEMO

df1 <- structure(list(NAME = c("AAA", "BBB", "CCC"), ID = c(1L, 3L, 
 6L), col3 = c(10L, 40L, 100L), col4 = c(20L, 20L, 200L), col5 = c(15L, 
 30L, 150L)), class = "data.frame", row.names = c(NA, -3L))

答案 2 :(得分:1)

您需要通过拆分条件来稍微更改代码的结构。

基本上,如果您担心MyView没有行,那么:

with myView as (
      Select t.tuneId, t.name
      from Tune t
      where <someCondition>
    )
select m.name, mv.name
from Map m left join
     myView mv 
     on m.id = mv.tuneID and
        <conditions on myView>
where <conditions not on myView> ;

如果map可能没有行,则角色将颠倒:

with myView as (
      Select t.tuneId, t.name
      from Tune t
      where <someCondition>
    )
select m.name, mv.name
from myView mv left join
     Map m
     on m.id = mv.tuneID and
        <conditions on map>
where <conditions not on map> ;