SQL: Left Outer Join, другой GROUP BY, нужно реплицировать записи? - PullRequest
0 голосов
/ 31 октября 2011

У меня есть информация о счетах в двух таблицах (A, B). Все записи в A уникальны на уровне учетной записи (account_id), но в таблице B учетные записи идентифицируются по account_id и month_start_dt, поэтому каждая учетная запись может существовать в ноль или более месяцев.

Проблема в том, что когда я оставил внешнее объединение от А до В, чтобы объединенная таблица содержала все записи из А с записями из В (по счетам, по месяцам), то любая учетная запись, которая не существует в таблице В в течение определенного месяца, нет записи за этот месяц.

Желаемый результат: если учетная запись не существует в таблице B в течение определенного месяца, создайте запись для этой учетной записи в объединенной таблице с month_start_dt и 0 для всех переменных, выбранных из B.

В нынешнем виде я могу заставить объединение работать, когда все учетные записи, не отображаемые в B (не появляющиеся вообще ни в каком месяце), имеют 0 значений для всех переменных, выбранных из B (используя nvl (variable, 0)) но эти учетные записи имеют только одну запись. Они должны быть по одному на каждый месяц.

Ответы [ 3 ]

1 голос
/ 01 ноября 2011

Я не понимаю, почему вам нужно внешнее соединение.При этом используются стандартные SQL EXCEPT (MINUS в Oracle):

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
);
1 голос
/ 01 ноября 2011

Вы можете использовать таблицу Tally Calendar с месяцами (от нескольких лет). Смотрите этот похожий вопрос: Как создать таблицу Calender на 100 лет в 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
1 голос
/ 01 ноября 2011

Создайте временную таблицу с количеством записей, которые вы хотите для несуществующих строк, и соедините справа результат первого запроса.

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

попробуйте это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...