SQL:Left Outer Join,不同的GROUP BY,需要复制记录吗?

时间:2011-10-31 19:59:12

标签: sql join

我在两个表(A,B)中有关于帐户的信息。 A中的记录在帐户级别(account_id)都是唯一的,但在表B中,帐户由account_id和month_start_dt标识,因此每个帐户可能存在零个或多个月。

问题是,当我将外部联接A添加到B时,联接表包含来自A的所有记录以及来自B的记录(按帐户,按月)任何在给定月份的表B中不存在的帐户没有那个月的记录。

期望的结果:如果某个月的表B中不存在某个帐户,请在联接表中使用month_start_dt创建该帐户的记录,并为从B中选择的所有变量创建0。

就目前而言,我可以让联接工作,其中所有未出现在B中的帐户(在任何月份都没有显示)对于从B中选择的所有变量都有0值(使用nvl(变量,0))但是,这些帐户只有一个记录。他们每个月应该有一个。

3 个答案:

答案 0 :(得分:1)

创建一个临时表,其中包含您想要的不存在行的记录数,并右键加入第一个查询的结果。

select tbl.* from ( select * from A left join B on a.col1 = b.col2) tbl join tmpTable on tbl.col2 = tmpTable.zerocol

试试这个。

答案 1 :(得分:1)

我不明白为什么你需要一个外连接。这使用标准SQL的EXCEPT(Oracle中的MINUS):

SELECT account_id, month_start_dt, all_variables 
  FROM B
UNION
(
 SELECT account_id, month_start_dt, 0 AS all_variables
   FROM A 
        CROSS JOIN (
                    SELECT DISTINCT month_start_dt
                      FROM B
                   ) AS DT1
 EXCEPT 
 SELECT account_id, month_start_dt, 0 AS all_variables
   FROM B
);

答案 2 :(得分:1)

你可以使用一个标记日历表,有几个月(几年)。看到类似的问题:How to create a Calender table for 100 years in Sql

然后:

FROM 
        A
    CROSS JOIN
        ( SELECT y
               , m
          FROM Calendar
          WHERE (   y = @start_year
                AND m >= @start_month
                )
             OR (   y > @start_year
                AND y < @end_year
                )
             OR (   y = @end_year
                AND m <= @end_month
                )
        ) AS C
    LEFT JOIN
        B
            ON  B.account_id = A.account_id
            AND YEAR(B.start_date) = C.y
            AND MONTH(B.start_date) = C.m