需要内部联接的帮助(自联接)

时间:2011-08-10 03:55:57

标签: sql oracle inner-join

我有一个包含以下架构的表:

Table1
Id       varchar2
name     varchar2
class    varchar2
JoinDate date
size     number

主键是id,name,class。

当我查询特定的ID时,名称我想返回按类分组的总和(大小),结果应该基于以下标准:

  1. 仅考虑具有与我不同的ID的行
  2. 仅考虑与我同名的行
  3. 如果另一个id的名称类组合与我的id的名称类组合匹配,那么只要JoinDate小于我的joinDate,就可以在该名称类组合中包含大小
  4. 如果其他ID的名称类组合与我的ID的名称类组合不匹配,则始终在总和中包含大小

    select 
        others.class,
        sum( case when others.class = mine.class and others.joindate <= mine.joindate then size
            when others.class = mine.class and others.joindate > mine.joindate then 0
            else size ) total_size
    from 
        table1 others
    inner join table1 mine
      on mine.name = others.name and
         mine.id != others.id
    where mine.name = :name and
          mine.id = :id
    group by class
    
  5. 以上是我到目前为止的查询,但它没有给我我想要的东西,因为它没有解决下面的情况:

    Id       Name    Class     JoinDate      Size 
    OtherId  Mark    Class1    Aug-20-2010   1
    OtherId  Mark    Class2    Aug-20-2010   1
    OtherId  Mark    Class3    Aug-30-2010   1
    MyId     John    Class1    Aug-21-2010   1
    MyId     John    Class4    Aug-21-2010   1
    MyId     John    Class3    Aug-29-2010   1
    

    我想要的是:

    Class1 1
    Class2 1
    Class3 0
    Class4 0
    

    这不是我得到的。

1 个答案:

答案 0 :(得分:1)

INNER JOIN确保至少存在一个关系 - 获取零的唯一方法是使用subselect或LEFT JOIN。尝试:

   SELECT a.class,
          SUM(COALESCE(b.size, 0)) 
     FROM (SELECT DISTINCT t.class
             FROM TABLE1 t) a
LEFT JOIN TABLE1 b ON b.class = a.class
                  AND EXISTS (SELECT NULL
                                FROM TABLE 1 x
                               WHERE x.name = :name
                                 AND x.id = :id
                                 AND x.id != b.id
                                 AND x.name = b.name
                                 AND x.joindate >= b.joindate)
 GROUP BY a.class