IRA-00904: «БАЛАНС ХРАНИЛИЩА»: недопустимый идентификатор 00904. 00000 — «%s: недопустимый идентификатор» *Причина: *Действие: Ошибка в строке: 1 Столбец: 49

#sql #oracle

Вопрос:

Мне нужно создать запрос oracle, который приведет к следующему отчету

 Name    AccountId   DistributorBalance  DealerBalance   StoreBalance
 

Я должен извлечь данные из трех связанных таблиц, которые:

  • Партнеры
  • счета партнеров
  • счета

Партнеры повторят три раза, как самостоятельное соединение, и каждое соединение из трех самостоятельных соединений partner должно присоединиться partneraccounts к таблице; также таблица accounts должна присоединиться partneraccounts . Я создаю этот подзапрос и получаю следующую ошибку:

 Select dis.name,DistributorBalace,DealerBalance,StoreBalance From
(
 select dis.name,disa.credit-disa.debit DistributorBalace 
        from partners dis join
        partneraccounts disp on dis.partnerid=disp.partnerid
        join  accounts disa on disa.accountid=disp.accountid
        where dis.identitytypeid=19
        union all
select de.name, dea.credit-dea.debit DealerBalance from partners de join
        partneraccounts dep on dep.partnerid=de.partnerid
        join  accounts dea on dea.accountid=dep.accountid
        where de.identitytypeid=7
        union all
select ag.name,aga.credit-aga.debit StoreBalance from partners ag join
        partneraccounts apa on apa.partnerid=ag.partnerid
        join  accounts aga on aga.accountid=apa.accountid
        where ag.identitytypeid=8 ) A
 
 Error
ORA-00904: "STOREBALANCE": invalid identifier
00904. 00000 -  "%s: invalid identifier"
*Cause:    
*Action:
Error at Line: 1 Column: 49
 

Комментарии:

1. попробуйте ввести as ключевое select ag.name,aga.credit-aga.debit as StoreBalance слово и включить его во все запросы.

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

3. поскольку это объединение, все столбцы из всех запросов должны быть одного типа. удалите DistributorBalace , DealerBalance , StoreBalance из ваших запросов, а затем запустите его

4. Вы дали имя результату A подзапроса . Т. е. вы можете только выбрать A.name и т. Д.

5. Одни и те же таблицы во всех таблицах с ОБЪЕДИНЕНИЕМ. Разве вы не можете просто сделать один-единственный ВЫБОР?

Ответ №1:

Запрос ОБЪЕДИНЕНИЯ имеет проекцию самого верхнего подзапроса. В вашем случае это так name, DistributorBalance (обратите внимание на исправление опечатки). В этой проекции нет столбца, вызываемого StoreBalance , следовательно, ошибка.

Вам нужны все три баланса в выходных данных, поэтому вам нужны подзапросы, которые возвращают все три. Обратите внимание , что указанный вами вывод также требуется accountid , поэтому включите и это. Что-то вроде этого:

 select a.name
      ,a.accountid
      ,a.DistributorBalance
      ,a.DealerBalance
      ,a.StoreBalance
from (
  select dis.name
        ,disp.accountid
        ,disa.credit - disa.debit as DistributorBalance 
        ,cast(null as number)     as DealerBalance
        ,cast(null as number)     as StoreBalance
  from    partners        dis 
  join    partneraccounts disp on dis.partnerid = disp.partnerid
  join    accounts        disa on disa.accountid = disp.accountid
  where  dis.identitytypeid = 19
  union all
  select  de.name
          dea.accountid
         ,cast(null as number)   as DistributorBalance 
         ,dea.credit - dea.debit as DealerBalance 
         ,cast(null as number)   as StoreBalance
  from   partners        de 
  join   partneraccounts dep on dep.partnerid = de.partnerid
  join   accounts        dea on dea.accountid = dep.accountid
  where de.identitytypeid = 7
  union all
  select  ag.name
         ,aga.accountid
         ,cast(null as number)   as DistributorBalance
         ,cast(null as number)   as DealerBalance
         ,aga.credit - aga.debit as StoreBalance 
  from   partners        ag 
  join   partneraccounts apa on apa.partnerid = ag.partnerid
  join   accounts        aga on aga.accountid = apa.accountid
  where ag.identitytypeid = 8
) a
 

Честно говоря, запрос объединения, подобный этому, может быть не самым эффективным способом выполнения задач, в зависимости от характеристик данных (объем, распределение и т. Д.). Я оставляю запрос, как указано выше, потому что он отвечает на поставленный вопрос, но если бы время выполнения оказалось проблемой, я бы извлек соединения из трех таблиц в один подзапрос С предложением и заменил подзапросы ОБЪЕДИНЕНИЯ на выбор. Или просто используйте три выписки по ДЕЛУ для разных балансов. Этот рефакторинг оставлен в качестве упражнения для читателя 🙂

Комментарии:

1. Спасибо, братан, теперь ошибка устранена , но, как вы указали выше, результат не отвечает требуемым данным, должно отображаться только поле имени таблицы дистрибьютора bcz, в то время как результат выдает все три таблицы

Ответ №2:

Я думаю, что это было бы намного проще с условной агрегацией:

 select p.name,
       sum(case when p.identitytypeid = 19 then a.credit - a.debit end) as DistributorBalance,
       sum(case when p.identitytypeid = 7 then a.credit - a.debit end) as DealerBalance,
       sum(case when p.identitytypeid = 8 then a.credit - a.debit end) as StoreBalance
from partners p join
     partneraccounts pa
     on p.partnerid = pa.partnerid join
     accounts a
     on a.accountid = pa.accountid
group by p.name;