2013-06-04 2 views
2

enter image description here У меня такой вид структуры в моей базе. Мне нужно создать список имен сотрудников, за которыми следуют имена их отделов и офисов. К настоящему времени я пришел на этот запрос:SQL-запрос в запросе

ALTER PROCEDURE FilterEmpList 
    @empName nvarchar(250) = null, 
    @empDepID int = null, 
    @empOfficeID int = null, 
    @empPosID int = null  
AS 
BEGIN 
SELECT 
    E.emp_id AS 'emp_id', 
    E.emp_name AS 'emp_name',  
    (SELECT pos_name FROM Positions WHERE pos_id=EP.pos_id) AS 'pos_name', 
    (SELECT dep_name FROM Departments WHERE dep_id=OS.dep_id) AS 'dep_name', 
    (SELECT office_name FROM Offices WHERE office_id=OS.office_id) AS 'office_name' 
FROM 
    Org_Structure OS INNER JOIN (Emp_Positions EP INNER JOIN Employees E ON EP.emp_id=E.emp_id) ON OS.chain_id=EP.chain_id  
WHERE 
    (E.emp_name LIKE '%'[email protected]+'%' OR @empName IS NULL) 
    AND 
    (OS.dep_id = @empDepID OR @empDepID IS NULL) 
    AND 
    (OS.office_id = @empOfficeID OR @empOfficeID IS NULL) 
    AND 
    (EP.pos_id = @empPosID OR @empPosID IS NULL) 
END 

Когда я исполняю его таким образом Exec FilterEmpList, возникает ошибка: Недопустимый объект имя «EP».

Это очень сложно для меня, этот вопрос мой максимум и взял меня целый день ... Помогите мне с предложениями, пожалуйста.

Следующий выпуск

Теперь у меня есть еще одна проблема с этим запросом. Если office_id или dep_id в Org_Structure равен NULL, он не возвращает эту запись вообще. Что-то не так с предложением WHERE.

Решение этой проблемы с WHERE пункт находится в этом другом моей теме: WHERE clause - record with a NULL column is not displayed

Спасибо всем. Проблема была решена

ответ

1

Возможно это будет полезно для вас -

ALTER PROCEDURE dbo.FilterEmpList 
    @empName nvarchar(250) = null, 
    @empDepID int = null, 
    @empOfficeID int = null, 
    @empPosID int = null  
AS 
BEGIN 

    SELECT 
     E.emp_id, 
     E.emp_name,  
     p.pos_name, 
     d.dep_name, 
     o.office_name 
    FROM dbo.Org_Structure OS 
    JOIN dbo.Emp_Positions EP ON OS.chain_id=EP.chain_id 
    /*LEFT*/ JOIN dbo.Employees E ON EP.emp_id=E.emp_id 
    /*LEFT*/ JOIN dbo.Positions p ON p.pos_id=EP.pos_id 
    /*LEFT*/ JOIN dbo.Departments d ON d.dep_id=OS.dep_id 
    JOIN dbo.Offices o ON o.office_id=OS.office_id 
    WHERE (
       E.emp_name LIKE '%'[email protected]+'%' 
      OR 
       @empName IS NULL 
     ) 
     AND OS.dep_id = ISNULL(@empDepID, OS.dep_id) 
     AND OS.office_id = ISNULL(@empOfficeID, OS.office_id) 
     AND EP.pos_id = ISNULL(@empPosID, EP.pos_id) 

END 
+0

Спасибо, я попробую это через час и отправлю отзыв. – SWA

+0

Хорошо, я только что попробовал отредактированный пример и, похоже, работает). Я попробую с реальными данными за несколько минут. – SWA

+0

Проблема с ** ГДЕ **. Если одно из полей в ** ОС ** является NULL (например, для некоторых сотрудников ** office_id = NULL **, потому что они принадлежат всему отделу), сотрудник не будет отображаться в результатах поиска ... – SWA

1

Некоторые из вас кода имеет получили неуместны я думаю. Попробуйте это ...

SELECT 
    E.emp_id AS 'emp_id', 
    E.emp_name AS 'emp_name',  
    P.pos_name AS 'pos_name', 
    D.dep_name AS 'dep_name', 
    O.office_name AS 'office_name' 
FROM 
    Org_Structure OS 
    INNER JOIN Emp_Positions EP ON OS.chain_id=EP.chain_id 
    INNER JOIN Employees E ON EP.emp_id=E.emp_id  
    LEFT JOIN Positions P ON P.pos_id=EP.pos_id 
    LEFT JOIN Departments D ON D.dep_id=OS.dep_id 
    LEFT JOIN Offices O ON O.office_id=OS.office_id 
WHERE 
    (E.emp_name LIKE '%'[email protected]+'%' OR @empName IS NULL) 
    AND 
    (OS.dep_id = @empDepID OR @empDepID IS NULL) 
    AND 
    (COALESCE(O.office_id,@empOfficeID) = @empOfficeID OR @empOfficeID IS NULL) 
    AND 
    (EP.pos_id = @empPosID OR @empPosID IS NULL) 
+0

Я нашел только разница в вашем примере - в разделе FROM. Я изменил свой запрос, но он по-прежнему показывает ту же ошибку ... – SWA

+0

@ Vladimir Я переместил подзапросы из SELECT, поскольку ссылка на EP внутри них могла быть проблемой –

+0

Да, получилось, спасибо. Теперь у меня другая проблема с предложением WHERE. Он не показывает записи с помощью office_id = NULL ... – SWA

1

Вы не можете ссылаться на inline select table из своего объема. я предлагаю использовать естественное соединение, как:

Select Emp_ID,Emp_Name,Dep_Name,Office_Name,Pos_Name 
From Employees e 
Join Emp_positions ep on ep.Emp_ID = e.Emp_ID 
Join Org_Structue os on os.Chain_ID = ep.Chain_ID 
Join Departments d on d.Dep_ID = os.Dep_ID 
Join Offices o on o.office_ID = os.Office_ID 
Join Positions p on p.Pos_ID = os.Pos_ID 
Where (E.emp_name LIKE '%'[email protected]+'%' OR @empName IS NULL) 
    AND 
    (OS.dep_id = @empDepID OR @empDepID IS NULL) 
    AND 
    (OS.office_id = @empOfficeID OR @empOfficeID IS NULL) 
    AND 
    (EP.pos_id = @empPosID OR @empPosID IS NULL) 
+0

Да, я пробовал это, и он работает, спасибо! Теперь у меня проблема с ** ГДЕ **. Он не показывает сотрудников с office_id = NULL. – SWA

1

Ваш запрос не будет, потому что вы пытаетесь присоединиться к EP Org_structure таблице, но это EP находится внутри скобок. Это запрещено. Попробуйте ниже

ALTER PROCEDURE FilterEmpList 
@empName nvarchar(250) = null, 
@empDepID int = null, 
@empOfficeID int = null, 
@empPosID int = null  
AS 
    BEGIN 
SELECT 
E.emp_id AS 'emp_id', 
E.emp_name AS 'emp_name',  
(SELECT pos_name FROM Positions WHERE pos_id=EP.pos_id) AS 'pos_name', 
(SELECT dep_name FROM Departments WHERE dep_id=OS.dep_id) AS 'dep_name', 
(SELECT office_name FROM Offices WHERE office_id=OS.office_id) AS 'office_name' 
FROM 
    Org_Structure OS 
    INNER JOIN Emp_Positions EP ON OS.chain_id=EP.chain_id 
    INNER JOIN Employees E ON EP.emp_id=E.emp_id  
WHERE 
(E.emp_name LIKE '%'[email protected]+'%' OR @empName IS NULL) 
AND 
(OS.dep_id = @empDepID OR @empDepID IS NULL) 
AND 
(OS.office_id = @empOfficeID OR @empOfficeID IS NULL) 
AND 
(EP.pos_id = @empPosID OR @empPosID IS NULL) 
END 
2

Существует проблема с вашим внутренним соединением/присоединением. После просмотра го запроса и ERD я предполагаю, что вы смотрите на это,

ALTER PROCEDURE FilterEmpList 
    @empName nvarchar(250) = null, 
    @empDepID int = null, 
    @empOfficeID int = null, 
    @empPosID int = null  
AS 
BEGIN 
SELECT 
    E.emp_id AS 'emp_id', 
    E.emp_name AS 'emp_name',  
    (SELECT pos_name FROM Positions WHERE pos_id=EP.pos_id) AS 'pos_name', 
    (SELECT dep_name FROM Departments WHERE dep_id=OS.dep_id) AS 'dep_name', 
    (SELECT office_name FROM Offices WHERE office_id=OS.office_id) AS 'office_name' 
FROM 
    Org_Structure OS 
INNER JOIN Emp_Positions EP ON EP.ChainId == Emp_Positions.ChainId 
INNER JOIN Employees E ON EP.emp_id=E.emp_id  
WHERE 
    (E.emp_name LIKE '%'[email protected]+'%' OR @empName IS NULL) 
    AND 
    (OS.dep_id = @empDepID OR @empDepID IS NULL) 
    AND 
    (OS.office_id = @empOfficeID OR @empOfficeID IS NULL) 
    AND 
    (EP.pos_id = @empPosID OR @empPosID IS NULL) 
END 

Также попробуйте сделать Псевдонимы более readible.

Благодаря

0

привет вы проверили, что ваша таблица EMP_Positions существует?

+0

Да, он существует. – SWA

Смежные вопросы