left join并显示左表中的所有行,如果右表不存在则返回null

时间:2014-05-03 13:41:28

标签: sql sql-server sql-server-2012

我有两张桌子

1)m_Year包含月份和年份:

month   year   
5       2013   
6       2013   
7       2013   
8       2013   
9       2013   
10      2013   

2)库存表,其中包含itemcode,month,year,stock as:

itemcode  month   year  stock 
AG1       5       2013  20
AG1       7       2013  10
AG1       9       2013  5
AG1       10      2013  20

结果应该是:

itemcode  month   year  stock 
AG1       5       2013  20
AG1       6       2013  null
AG1       7       2013  10    
AG1       8       2013  null
AG1       9       2013  5
AG1       10      2013  20

以下是我正在使用的查询:

select a.ICode, MONTH(a.VDate) as month, YEAR(a.vdate) as year,
   sum(isnull(a.qty, 0)) as stock       
from t_Stock a left join m_year as b on month(a.vdate) = b.month and year(a.vdate)= b.year
group by a.ICode, MONTH(a.VDate), YEAR(a.vdate)
order by a.icode, YEAR(a.vdate), MONTH(a.VDate);

产生以下结果:

itemcode  month   year  stock 
AG1       5       2013  20
AG1       7       2013  10
AG1       9       2013  5
AG1       10      2013  20

2 个答案:

答案 0 :(得分:2)

如果您有多个代码,则需要先使用cross join生成所有行,然后使用left outer join获取数据:

select sic.ICode, MONTH(y.VDate) as [month], YEAR(y.vdate) as [year],
       sum(s.qty) as stock       
from m_year y cross join
     (select distinct s.ICode from stock) sic left outer join
    t_Stock s 
    on month(s.vdate) = y.month and year(s.vdate)= y.year and
       s.Icode = sic.Icode
group by sic.ICode, MONTH(y.VDate), YEAR(y.vdate)
order by sic.ICode, MONTH(y.VDate), YEAR(y.vdate);

请注意,聚合和选择列来自cross join中的表,而不是t_stock表。当left outer join失败时,这些列的值为NULL,这没有帮助。

答案 1 :(得分:2)

SQL Fiddle

MS SQL Server 2008架构设置

CREATE TABLE m_Year (month INT, year INT)

INSERT INTO m_Year  VALUES
(5 ,      2013),   
(6 ,      2013),   
(7 ,      2013), 
(8 ,      2013),   
(9 ,      2013),   
(10,      2013)


CREATE TABLE stock (itemcode VARCHAR(10),  month INT,year INT,  stock INT)
INSERT INTO Stock VALUES
('AG1',       5 ,      2013,  20),
('AG1',       7 ,      2013,  10),
('AG1',       9 ,      2013,  5),
('AG1',       10,      2013,  20)

查询1

select ISNULL(a.itemcode,'AG1') AS ItemCode 
      ,b.MONTH                  AS month
      ,b.YEAR                   AS year
      ,ISNULL(sum(a.stock), 0)  AS stock       
from  m_year as b  left join Stock a
on a.month = b.month and a.year = b.year
group by  a.itemcode
         ,b.MONTH     
         ,b.YEAR 

<强> Results

| ITEMCODE | MONTH | YEAR | STOCK |
|----------|-------|------|-------|
|      AG1 |     6 | 2013 |     0 |
|      AG1 |     8 | 2013 |     0 |
|      AG1 |     5 | 2013 |    20 |
|      AG1 |     7 | 2013 |    10 |
|      AG1 |     9 | 2013 |     5 |
|      AG1 |    10 | 2013 |    20 |