2015-04-27 3 views
1

Предполагая, что у меня есть следующая таблица базы данных Oracle user_data:счетных Четкие Менеджеры по каждой стране

USER Manager  Country 
User 1 Manager 1 Canada 
User 2 Manager 2 Canada 
User 3 Manager 3 Canada 
User 4 Manager 1 England 
User 5 Manager 1 Scotland 
User 6 Manager 1 Scotland 
User 7 Manager 1 Scotland 
User 8 Manager 1 England 

У нас есть бизнес-правило, что менеджер несет ответственность только для страны, если они являются единственным менеджером пользователей в этой стране , Например, с предоставленными данными менеджер 1 несет ответственность только за Шотландию и Англию, но не за Канаду. У меня есть решение, но это очень медленный процесс, и я думаю, что должен быть лучший способ запроса данных:

SELECT DISTINCT manager, country 
FROM user_data 
WHERE country IN (
    SELECT country FROM (
     SELECT DISTINCT country, manager 
     FROM user_data 
    ) 
    GROUP BY country 
    HAVING count(country) = 1 
); 

Любые идеи о более эффективном запросе, который определяет, какой менеджер несет ответственность за страну?

+2

какая версия Oracle? сколько строк в таблице? Если запрос медленный, вы можете показать план объяснения? – kevinsky

+0

Правильно ли выполняется запрос ur? – Bikku

ответ

1

Вы можете попробовать с left join и is not null:

функция
select distinct t1.manager 
from user_data t1 
left join (
    select country 
    from user_data 
    group by country 
    having count(distinct manager) = 1) t2 on t1.country = t2.country 
where t2.country is not null 
+0

Можете ли вы объяснить, почему 'left join' /' is not null' будет более эффективным, чем стандартное (внутреннее) соединение (что синтаксически одно и то же, если я не ошибаюсь)? – ymog

+0

@ymog: На самом деле, я говорю, что это может быть достигнуто без ненужного подзапроса. И поскольку это пример шаблона антисоединения, я использовал один из вариантов - 'left join' /' not null'. Вы можете прочитать больше [здесь] (http://explainextended.com/2009/09/17/not-in-vs-not-exists-vs-left-join-is-null-oracle/). – potashin

+0

Спасибо за решение, он работает хорошо. Просто любопытно, не «DISTINCT» нахмурился, в том смысле, что само соединение должно заботиться о нечетких значениях (например, о внутреннем соединении)? – eniacAvenger

0

проверка stragg() это может ЛФВЭ, я не проверял ниже SQL.

SELECT stragg(manager), country 
FROM user_data 
GROUP BY country 
HAVING count(country) = 1 
Смежные вопросы