Однорядный подзапрос Oracle возвращает более одной ошибки строки

#sql #oracle #oracle11g #case

#sql #Oracle #oracle11g #случай

Вопрос:

У меня есть сценарий. Можно ли это сделать с помощью одного запроса?

  • Таблица Company: информация об одной компании с CPK в качестве первичного ключа и одним менеджером, руководителем, персоналом, привязанным к нему

  • Таблица сотрудников: для каждой компании есть сотрудники (1 или более, может быть до 500) с уникальным идентификатором EmpID и прикрепленными к нему менеджером, руководителем, персоналом

  • Информация о сотрудниках таблицы (для использования веб-приложения): ему назначен 1 или более менеджер, ведущий, отдел кадров (или может быть ВСЕ, ВСЕ, ВСЕ, что означает, что он может видеть все)

Итак:

 Company
--------
CPK (PK)
Manager
Lead
HR

Employees 
--------
empID (PK)
CPK (FK)
Manager
Lead
HR

EmployeesInfo
-------------
USER_ID (FK)
Manager
Lead
HR
  

Web —> При входе пользователя в систему он должен получить всю информацию о компании.Если у него есть доступ к этой компании или любому сотруднику в этой компании, тогда эта строка включена, иначе она выделена серым цветом (отключена), если это «Все», тогда он может редактировать каждую запись

Например: User1 присваивается Manager1, Lead1 и HR1.
Затем он может редактировать все записи из Company, где Manager = Manager1, Lead = Lead1 и HR = HR1.
Также записи в компании, в которой работают сотрудники компании.CPK = Сотрудник.CPK и сотрудник.Manager = Manager1 и Employee.Lead = Lead1 и Employee .HR = HR1

Мой запрос до сих пор, но

 select t2.MANAGER from Employees t2 where t2.CPK  = t1.CPK
  

возвращает ожидаемую множественную запись, что мне делать???

 SELECT  t1.*,
      --All condition
      CASE WHEN (SELECT MANAGER FROM EmployeesInfo WHERE USER_ID=44) = 'All' then 1
           ELSE(
                --Check for Company
                CASE 
                WHEN t1.MANAGER  in (SELECT MANAGER FROM EmployeesInfo WHERE USER_ID=44) then 1
                WHEN t1.LEAD in (SELECT LEAD FROM EmployeesInfo WHERE USER_ID=44) then 1
                WHEN t1.HR  in (SELECT HR FROM EmployeesInfo WHERE USER_ID=44) then 1
           ELSE(
                --Check Employee M,L,HR for that Company 
                CASE
                WHEN (SELECT t2.MANAGER FROM Employees t2 WHERE t2.CPK  = t1.CPK) in 
                       (SELECT MANAGER FROM EmployeesInfo WHERE USER_ID=44) then 1
                WHEN (SELECT t2.LEAD FROM Employees t2 WHERE t2.CPK = t1.CPK ) in 
                       (SELECT LEAD FROM EmployeesInfo WHERE USER_ID=44) then 1
                WHEN (SELECT t2.HR FROM Employees t2 WHERE t2.CPK  = t1.CPK  ) in 
                       (SELECT HR FROM EmployeesInfo WHERE USER_ID=44) then 1
                ELSE 0 END
                )
           END
           )
      END AS Grey_Out 
FROM Company t1 
WHERE  t1.CPK  ='1234'
  

Наконец, я должен получить all Company с полем grey_out как (1 или 0), затем я буду использовать поле Grey_Out для определения того, следует ли его сделать редактируемым.

Ответ №1:

У меня болит голова, просто чтобы понять дизайн вашей таблицы.

Вы слышали о соединениях?

 SELECT DISTINCT c.*, 
       CASE WHEN e.empid IS NOT NULL OR ei.USER_ID IS NOT NULL
            THEN 1
            ELSE 0
       END AS Grey_Out 
FROM Company c
    LEFT OUTER JOIN EmployeesInfo ei
        ON c.MANAGER = ei.MANAGER 
        OR c.LEAD = ei.LEAD
        OR c.HR = ei.HR
    LEFT OUTER JOIN Employees e
        ON e.CPK = c.CPK
        AND (
               e.MANAGER = ei.MANAGER
            OR e.LEAD = ei.LEAD
            OR e.HR = ei.HR
        )
WHERE c.CPK = '1234'
AND ei.USER_ID = 44
  

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

1. Спасибо Scorpi0. Но он вернул 0 записей. Кстати, мы не можем изменить дизайн таблицы, который запущен и разработан сторонним поставщиком. Поэтому мы можем просто использовать как есть. Я слышал о соединениях и использовал его

Ответ №2:

Изменить

 case
    when (select t2.MANAGER from Table2 t2 where t2.CPK  = t1.CPK) in 
      (Select MANAGER from Table3 where USER_ID=44) then 1
  

Для

 case
    when exists
        (select *
        from 
            Table3 t3
            inner join table2 t2 on t2.manager = t3.manager
        where 
            t3.USER_ID=44 and t2.CPK = t1.CPK) then 1
  

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

1. Спасибо Golez Trol за вашу помощь