2015-09-25 6 views
1

У меня проблема:Эффективный sql-запрос для поиска составного ключа в таблице?

Предположим, что есть таблица EMP с данными о сотрудниках. Колонны, которые нас интересуют, это DeptID и ManagerID.

У меня есть список (скажем) 50 записей в следующем формате -

deptId1, managerid1 так на

Самый эффективный способ сделать это в SQL Server?

Например, если бы я был только поиск по ManagerID, я мог бы сделать следующее:

Select * from EMP where ManagerID in (id1, id2, ..., id50); 

Однако в случае пары, я вынужден выполнить следующий запрос в 50 раз:

select * from EMP where ManagerID = Mid1 
         AND DeptID = deptid; 

EDIT:

Один подход, который я придумал:

Если изменить отчет, чтобы иметь DeptID + ManagerID

я могу сделать что-то вроде этого:

WITH TEMPTABLE AS 
select * from EMP where 
       (DeptID + ManagerID) IN (sumID1 , sumID2.....) 
select * from TEMPTABLE where ManagerID = Mid1 
         AND DeptID = deptid; 

Как вы думаете, это может быть быстрее?

Что еще более важно, мы можем каким-то образом использовать индекс (DeptID + ManagerID)?

+4

«Выберите * из EMP где (ManagerID, DeptId) в ((id1, dep1), (id2, dep2), ...)' Oracle должен поддерживать конструкторы строк – lad2025

+0

К сожалению, этот запрос дает ошибку: недействительный реляционный оператор – rents

+0

Попробуйте: 'Выберите * из EMP где (ManagerID, DeptId) в (SELECT id1 AS col1, dep1 как col2 FROM dual UNION ALL SELECT id2, dep2 FROM dual)' – lad2025

ответ

1

Вы можете использовать = ANY:

SqlFiddleDemo

SELECT * 
FROM EMP 
WHERE (ManagerID, DeptId) = ANY ((1,1), (2,4)); 

или IN + subquery:

SELECT * 
FROM EMP 
WHERE (ManagerID, DeptId) IN (SELECT 1 AS col1, 1 AS col2 FROM dual 
           UNION ALL SELECT 2,4  FROM dual) 

или CTE/subquery + JOIN:

WITH cte(ManagerId, DeptID) AS 
(
    SELECT 1 AS ManagerId, 2 AS DeptID FROM dual 
    UNION ALL SELECT 2, 4    FROM dual 
) 
SELECT * 
FROM EMP e 
JOIN cte c 
    ON e.ManagerId = c.ManagerId 
AND e.DeptId = c.DeptId; 

или просто IN, как в комментариях:

SqlFiddleDemo_IN

SELECT * 
FROM EMP 
WHERE (ManagerID, DeptId) IN ((1,1), (2,4)); 

EDIT:

Совмещение в йо u предложил (DeptID + ManagerID) IN (sumID1 , sumID2.....) не очень хорошая идея, например, (1+5) = (3+3).Вы получите неточные результаты.

+0

@rents См. Обновленный ответ – lad2025

+0

Я прошел через исходный код, 1 год, поэтому простите меня за то, что я не дал здесь правильной проблемы. Я опубликую эту проблему в отдельном вопросе, поскольку это вызовет беспорядок и, надеюсь, кто-то сможет предложить элегантный подход. Я также расскажу об этом здесь. – rents

+0

Кроме того, если вы внимательно посмотрите в моем предлагаемом подходе, я создаю временную таблицу (TEMPTABLE) для аккуратных + неточных записей и затем запускаю окончательный запрос в этом наборе. Что-то вроде хэширования. – rents

0

Возможно ли загрузить список в таблицу базы данных? Затем вы можете присоединиться к своей таблице EMP к этому в двух условиях.

SELECT * FROM EMP e 
JOIN DEPT_MGR d 
ON e.ManagerID = d.ManagerID 
AND e.DeptID = d.DeptID 
+0

Не означает ли это создание новой таблицы в модели данных? Вы не можете изменить модель данных. – rents

1
select 
    * 
from 
    emp 
where 
    (managerid, departmentid) in (
    (1, 2), 
    (2, 3) 
) 
+0

Это правильный ответ, но на первом месте (как комментарий) ответил @ lad2025, отметив его ответ как принятый. – rents

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