Избавление от предложения where, если значение = 'ADMIN' - PullRequest
0 голосов
/ 12 марта 2020

Итак, есть главная таблица (с именем Table1), и у одного из столбцов в этой таблице есть столбец с именем компании. и есть еще одна таблица с именем Account, и в этой таблице есть имена пользователей и названия компаний, с которыми связан пользователь. поэтому должна отображаться только информация в таблице 1, связанная с компанией пользователя, если только она не является администратором.

Я работаю над приложением APEX для Oracle

В настоящее время у меня есть запрос, который выглядит следующим образом:

Select
SUPPLIER,
sum(NUMBER_OF_TICKETS) TICKETS,
round((sum(NUMBER_OF_TICKETS*AMOUNT_PAYABLE__FOREIGN_CUR)*.1),2) COMMISION,
round(sum(NUMBER_OF_TICKETS*AMOUNT_PAYABLE__FOREIGN_CUR),2) TOTAL_SALES,
round((sum(NUMBER_OF_TICKETS*AMOUNT_PAYABLE__FOREIGN_CUR)-(sum(NUMBER_OF_TICKETS*AMOUNT_PAYABLE__FOREIGN_CUR)*.1)),2) COMPANY_OWE,
CURRENCY
FROM TABLE1
WHERE
 Supplier = (select COMPANYNAME from Account where lower(USERNAME)=lower(:APP_USER)) AND
     PURCHASE_DATE_AND_TIME >= TO_DATE(:P2_START)
      AND PURCHASE_DATE_AND_TIME < TO_DATE(:P2_END)+ 1
group by
SUPPLIER,
CURRENCY


Я работаю в беду с функцией "ГДЕ". Потому что я в основном хочу иметь if ... then ... (или оператор case в этом случае), где

IF
((выберите COMPANYNAME из учетной записи, где ниже (USERNAME) = ниже (: APP_USER)) == 'COMPANY1' AND (выберите USERTYPE из учетной записи, где ниже (USERNAME) = ниже (: APP_USER)) == 'ADMIN')

THEN
показать все строки; aka, Поставщик = (выберите COMPANYNAME из BBAccount, где ниже (USERNAME) = ниже (: APP_USER)) в запросе

Кто-нибудь есть какие-либо идеи о том, как go о написании запроса для этого?
Я пытался сделать

Случай оператор Когда оператор Тогда NULL

Это не работает

Я попытался нарисовать диаграмму, дайте мне знать, если это сделает это более ясным:
Диаграмма

Ответы [ 3 ]

1 голос
/ 12 марта 2020

Что касается Apex, я бы предложил вам создать функцию:

create or replace function f_is_admin_01 (par_app_user in varchar2)
  return number
is
  -- function returns 1 if PAR_APP_USER is admin; otherwise, it returns 0
  l_usertype  account.usertype%type;
begin
  select a.usertype
    into l_usertype
    from account a
    where lower(a.username) = lower(par_app_user);

  return case when l_usertype = 'ADMIN' then 1
              else 0
         end;

exception
  when no_data_found then
    return 0;
end;

Теперь вы можете использовать ее в запросе как

select ...
from account a join table1 t on a.companyname = t.companyname
where (lower(a.username) = lower(:APP_USER) or f_is_admin_01 (:APP_USER) = 1)
  and t.purchasedate ...

Такой подход ( Я имею в виду, иметь функцию) может быть полезным в другом месте; например, если вы хотите показывать определенную область страницы только администраторам - вы бы поместили

return f_is_admin_01(:APP_USER) = 1;

в «Состояние стороны сервера» региона (его типом будет «Функция, возвращающая логическое значение»).

Посмотрите, поможет ли это.

0 голосов
/ 12 марта 2020

EXISTS(...) ваш друг:


Select SUPPLIER
        ,sum(NUMBER_OF_TICKETS) TICKETS
        ,round((sum(NUMBER_OF_TICKETS*AMOUNT_PAYABLE__FOREIGN_CUR)*.1),2) COMMISION
        ,round(sum(NUMBER_OF_TICKETS*AMOUNT_PAYABLE__FOREIGN_CUR),2) TOTAL_SALES
        ,round((sum(NUMBER_OF_TICKETS*AMOUNT_PAYABLE__FOREIGN_CUR)
              -(sum(NUMBER_OF_TICKETS*AMOUNT_PAYABLE__FOREIGN_CUR)*.1)),2) COMPANY_OWE
        , CURRENCY
FROM TABLE1 t
WHERE EXISTS (
        SELECT 1
        from Account x
        where x.Supplier = t.COMPANYNAME
        AND lower(x.USERNAME) = lower(:APP_USER))
        AND x.PURCHASE_DATE_AND_TIME >= TO_DATE(:P2_START)
        AND x.PURCHASE_DATE_AND_TIME < TO_DATE(:P2_END)+ 1
        )
group by SUPPLIER, CURRENCY
        ;
0 голосов
/ 12 марта 2020

Итак, есть главная таблица (с именем Table1), и у одного из столбцов в этой таблице есть столбец с именем компании. и есть еще одна таблица с именем Account, и в этой таблице есть имена пользователей и названия компаний, с которыми связан пользователь. поэтому должна отображаться только информация в таблице 1, связанная с компанией пользователя, если только она не является администратором

Я думаю, что вы можете просто присоединиться - что-то вроде:

SELECT ...
FROM TABLE1 t
INNER JOIN ACCOUNTS a 
    ON  lower(a.username) = lower(:APP_USER)
    AND (a.companyname = t.companyname OR a.usertype = 'ADMIN')
WHERE
    t.purchase_date_and_time >= TO_DATE(:P2_START)
    AND t.purchase_date_and_time < TO_DATE(:P2_END) + 1
GROUP BY ...

Внутреннее объединение ACCOUNTS предназначено для реализации логики фильтрации c: пользователь должен либо принадлежать к той же компании, либо иметь тип администратора.

...