Левый присоединиться с результатом COALESCE - PullRequest
0 голосов
/ 30 апреля 2018
    SELECT  *
      FROM  TBDA temp
 LEFT JOIN (
            SELECT
            (
              COALESCE (
                 (
                    SELECT sum_payment
                      FROM TBDA_REPAYMENT 
                     WHERE isdn = temp.isdn
                       AND tr_month = temp.tr_month
                       AND tr_year = temp.tr_year 
                ),
                 (
                    SELECT sum_payment
                      FROM TBDA_PAYNEW 
                     WHERE isdn = temp.isdn
                       AND tr_month = temp.tr_month
                       AND tr_year = temp.tr_year 
                )
              )
            )
          )
  • В таблице TBDA есть isdn, tr_month, tr_year
  • Таблица TBDA_REPAYMENT имеет isdn, tr_month, tr_year, sum_payment
  • Таблица TBDA_PAYNEW имеет isdn, tr_month, tr_year, sum_payment

Ожидаемый результат:

Таблица всех полей TBDA с sum_payment, ищите sum_payment из двух таблиц (TBDA_REPAYMENT & TBDA_PAYNEW) по ISDN (таблица TBDA), сравнивая isdn, tr_month, tr_year, если sum_payment существует в одной из двух таблиц (TBDA_REPAYMENT & TBDA_PAYN ) затем добавьте его к результатам, иначе оно будет нулевым.

Я получаю сообщение об ошибке:

[Err] 42000 - [SQL Server] Неверный синтаксис рядом с ')'.

Ответы [ 4 ]

0 голосов
/ 30 апреля 2018

Просто используйте коррелированные подзапросы:

SELECT t.*,
       IFNULL (  (SELECT r.sum_payment
                   FROM TBDA_REPAYMENT r
                   WHERE r.isdn = t.isdn AND
                         r.tr_month = t.tr_month AND
                         r.tr_year = t.tr_year 
                  ),
                  (SELECT p.sum_payment
                   FROM TBDA_PAYNEW p
                   WHERE p.isdn = t.isdn AND
                         p.tr_month = t.tr_month AND
                         p.tr_year = t.tr_year 
                  )
               )
        )
FROM TBDA t;

Хотя вы можете использовать APPLY, использование SELECT уже настаивает на том, чтобы из подзапросов возвращалось не более одной строки.

Также обратите внимание на пару вещей. Сначала я заменил COALESCE() на IFNULL(). Хотя я предпочитаю COALESCE() (потому что он стандартный и более гибкий), код более эффективен с IFNULL(). COALESCE() заставляет SQL Server дважды оценить первый аргумент, если он не NULL.

Во-вторых, псевдонимы таблиц и полные имена столбцов должны использоваться везде в запросе.

0 голосов
/ 30 апреля 2018
SELECT
    *
FROM
    TBDA temp
Cross Apply (   SELECT  COALESCE (
                        (
                            SELECT
                                sum_payment
                            FROM
                                TBDA_REPAYMENT 
                            WHERE
                                isdn = temp.isdn
                            AND tr_month = temp.tr_month
                            AND tr_year = temp.tr_year 
                        ),
                        (
                            SELECT
                                sum_payment
                            FROM
                                TBDA_PAYNEW 
                            WHERE
                                isdn = temp.isdn
                            AND tr_month = temp.tr_month
                            AND tr_year = temp.tr_year 
                        )   
                    ) as First_Null_Value

            ) as value_table
0 голосов
/ 30 апреля 2018

Если не используется CROSS JOIN, CROSS APPLY или OUTER APPLY, требуется условие ON.
Отсюда и ошибка.
Хотя вы все еще можете сделать что-то вроде ... LEFT JOIN othertable ON (1=1).

Но вы можете переписать этот запрос, используя 2 левых соединения.

select 
 temp.*,
 coalesce(repay.sum_payment, paynew.sum_payment) as value_table
from TBDA temp
left join TBDA_REPAYMENT repay on (repay.isdn = temp.isdn and repay.tr_month = temp.tr_month and repay.tr_year = temp.tr_year)
left join TBDA_PAYNEW paynew on (paynew.isdn = temp.isdn and paynew.tr_month = temp.tr_month and paynew.tr_year = temp.tr_year);

Обратите внимание, что есть предположение, что таблицы TBDA_REPAYMENT & TBDA_PAYNEW имеют уникальность для 3 полей, используемых в объединении (isdn, tr_month, tr_year).

Или можно использовать синтаксис OUTER APPLY. И если нет уникальности (isdn, tr_month, tr_year), то вы можете использовать это для СУММЫ итога одновременно.

select 
 temp.*, repay.sum_payment as repay_sum_payment, paynew.sum_payment as  paynew_sum_payment,
 coalesce(repay.sum_payment, paynew.sum_payment) as value_table
from TBDA temp
outer apply
(
  select nullif(sum(rp.sum_payment),0) as sum_payment
  from TBDA_REPAYMENT rp 
  where rp.isdn = temp.isdn 
    and rp.tr_month = temp.tr_month 
    and rp.tr_year = temp.tr_year
) as repay
outer apply 
(
  select nullif(sum(pn.sum_payment),0) as sum_payment
  from TBDA_PAYNEW pn 
  where pn.isdn = temp.isdn 
    and pn.tr_month = temp.tr_month 
    and pn.tr_year = temp.tr_year
) as paynew;

Пример фрагмента:

declare @TBDA table (isdn int, tr_month int, tr_year int);
declare @TBDA_REPAYMENT table (isdn int, tr_month int, tr_year int, sum_payment int);
declare @TBDA_PAYNEW  table (isdn int, tr_month int, tr_year int, sum_payment int);

insert into @TBDA (isdn, tr_month, tr_year) values (1,6,2018),(2,6,2018);
insert into @TBDA_REPAYMENT (isdn, tr_month, tr_year, sum_payment) values (1,6,2018, 100);
insert into @TBDA_PAYNEW (isdn, tr_month, tr_year, sum_payment) values (1,6,2018, 200),(2,6,2018,100),(2,6,2018,200);

--
-- Using left join
--
select 
 temp.*, repay.sum_payment, paynew.sum_payment,
 coalesce(repay.sum_payment, paynew.sum_payment) as value_table
from @TBDA temp
left join @TBDA_REPAYMENT repay on (repay.isdn = temp.isdn and repay.tr_month = temp.tr_month and repay.tr_year = temp.tr_year)
left join @TBDA_PAYNEW paynew on (paynew.isdn = temp.isdn and paynew.tr_month = temp.tr_month and paynew.tr_year = temp.tr_year);

--
-- Using outer apply
--
select 
 temp.*, repay.sum_payment as repay_sum_payment, paynew.sum_payment as  paynew_sum_payment,
 coalesce(repay.sum_payment, paynew.sum_payment) as value_table
from @TBDA temp
outer apply
(
  select nullif(sum(rp.sum_payment),0) as sum_payment
  from @TBDA_REPAYMENT rp 
  where rp.isdn = temp.isdn 
    and rp.tr_month = temp.tr_month 
    and rp.tr_year = temp.tr_year
) as repay
outer apply 
(
  select nullif(sum(pn.sum_payment),0) as sum_payment
  from @TBDA_PAYNEW pn 
  where pn.isdn = temp.isdn 
    and pn.tr_month = temp.tr_month 
    and pn.tr_year = temp.tr_year
) as paynew;
0 голосов
/ 30 апреля 2018

Ошибка из-за не указания условия ON для LEFT JOIN.

LEFT JOIN без ON выдаст ошибку.

Если вы не хотите указывать какие-либо условия, попробуйте CROSS JOIN

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