Нужна помощь с внутренним соединением (самостоятельное соединение) - PullRequest
0 голосов
/ 10 августа 2011

У меня есть таблица со следующей схемой:

Table1
Id       varchar2
name     varchar2
class    varchar2
JoinDate date
size     number

Первичный ключ - это идентификатор, имя, класс.

Когда я запрашиваю конкретный идентификатор, имя, которое я хочу вернуть, сумма (размер), сгруппированная по классу, и результаты должны быть основаны на следующих критериях:

  1. Рассматривать только строки с другим Id, как у меня
  2. Рассматривать только строки с тем же именем, что и у меня
  3. Если комбинация класса имен для другого идентификатора совпадает с комбинацией класса имен для моего идентификатора, то включите размер в сумму, если JoinDate меньше моего joinDate для этой комбинации класса имен
  4. Если комбинация класса имен для другого идентификатора не совпадает с комбинацией класса имен для моего идентификатора, то всегда включайте размер в сумму

    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
    

Выше приведен запрос, но он не дает того, что я хочу, потому что не решает приведенный ниже случай:

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 Ответ

1 голос
/ 10 августа 2011

ВНУТРЕННЕЕ СОЕДИНЕНИЕ гарантирует, что существует хотя бы одно отношение - единственный способ получить нули - это либо с помощью выбора, либо ЛЕВОГО СОЕДИНЕНИЯ.Попробуйте:

   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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...