2015-12-05 2 views
3

Это база данных, жирный первичный ключ.Почему сложнее запрашивать объекты с более чем каждым vs меньше, чем некоторые?

  • works (person_name, company_name, salary)

Предположим, мы имеем эту проблему:

Найти имена всех сотрудников, которые зарабатывают больше, чем каждого работника малого Bank Corporation.

Предлагаемое решение:

Мы не можем легко вычислить набор сотрудников, которые зарабатывают больше, чем каждого работника малого Bank Corporation, но мы можем вычислить набор сотрудников, которые зарабатывают меньше, чем некоторые работники малого Bank Corporation. Мы вычитаем этот набор из набора всех сотрудников. Обратите внимание на меньшее или равное значение, и мы удаляем записи с тем же именем.

temp ← ∏person_name(σp(works⨯ρd(works))) 

где р

works.person_name ≠ d.person_name ∧ 
works.salary ≤ d.salary ∧ 
d.company_name = "Small Bank Corporation" 

Тогда ответ:

∏person_name(works) − temp 

Почему мы не можем легко вычислить множество людей, которые зарабатывают больше, чем каждый работник малого Bank Corporation ? И почему мы можем легко вычислить набор людей, которые зарабатывают меньше? Я этого не понимаю. Что делает works.salary < = d.salary точно делать? Занимает ли он цикл для каждого объекта .salary через все объекты d.salary и посмотреть, является ли оно < = для ВСЕХ объектов d.salary?

+1

Если вы ищете решение в SQL, существует много разных способов выражения этого запроса. –

+0

Кто предложил решение? Или вы спрашиваете, почему ваше решение непросто? –

+0

@EmacsUser Вопрос не в том, что вопрос, вопрос в том, почему два запроса, которые настолько похожи в одном смысле (значение), столь разные в другом (выражение алгебры/sql). – philipxy

ответ

2

Запрос может быть выражено довольно легко, как это:

select person_name 
from works 
where salary > (
    select max(salary) 
    from works 
    where company_name = 'Small Bank Corporation') 
1

Мы не можем легко вычислить набор сотрудников, которые зарабатывают больше, чем каждый работник малого Bank Corporation, но мы можем вычислить множество сотрудников, которые зарабатывают меньше, чем некоторые сотрудники Small Bank Corporation.

Это не неравенство, которое имеет значение. (Вы можете видеть это, просто изменяя их в своем.) Это ВСЕ ДЛЯ ВСЕХ/ВСЕХ ИЛИ ДЛЯ НЕКОТОРЫХ.

A предикат - это истинное или ложное заявление о заполнении (named-) пробелов).

-- person [W.P] works for company [W.C] for salary [W.S] 
W (W.P,W.C,W.S) 

Обратите внимание, что имя плюс его атрибуты является сокращенной версией предиката. Мы называем предикат переменной отношения, константы или выражения его , что означает.

Предположим, что выражения отношения e & f содержат строки, которые образуют предикатные выражения E & F true (соответственно). Операторы алгебры были сконструированы так, что:

R содержит строки, удовлетворяющие R (R.X, ...)
ρS(ewith attributes R.X) держит строки, удовлетворяющие E с RX заменена SX
e⨯f держит строки, удовлетворяющие Е и F
e-f держит строки, удовлетворяющие Е и НЕ F
eUf держит строки, удовлетворяющие E OR F
σcondition(e) имеет строки, удовлетворяющие Е И условие
πA(e) имеет строки, удовлетворяющие НЕКОТОРЫХ всех атрибутов, кроме: E

Просто так получилось, что для каждого небольшого изменения соотношения есть небольшое изменение в значении , Обратите внимание, что список не включает выражение ~(e) («дополнение»), которое содержит строки, где NOT E, то есть строки, которые не являются в e. Потому что (в общем) это много строк и нецелесообразно рассчитать. Но оказывается, что если мы никогда не хотим, чтобы эти строки являлись результатом запроса (и, как правило, мы этого не делаем), мы можем переписать их с помощью других операторов. ДЛЯ ВСЕХ A: E означает НЕ ДЛЯ НЕКОТОРЫХ A: НЕ E. Таким образом, запросы, связанные с FOR ALL, сложны, и мы не можем (в общем) иметь FORALL снаружи. Оригинал , означающий, не является сложным, но мы должны перестроить его на сложную формулировку, рассчитанную выражением сложного отношения.

Таким образом, ответ заключается в том, что отношение, в котором ДЛЯ НЕКОТОРЫХ A: E просто рассчитать и визуализировать, но отношение, в котором FOR ALL A: E использует сложные вызовы недорогих операторов для вычисления недорого и не является человеко-очевидная перестройка e.

(Существуют различные особые случаи использования FOR ALL, которые переводят непосредственно на простые вызовы различных операторов «деления». Но тогда особые случаи не имеют простых значений! Оказывается, проще всего выражать FOR ALL запросы с помощью операторов отношения подмножества.)

(см моих ответов & их вопросы here повторно предикатов & алгебры и here ре SQL.)

Что works.salary < = d.salary точно делать? Занимает ли он цикл для каждого works.salary entity через все объекты d.salary и посмотреть, является ли оно < = для ВСЕХ объектов d.salary?

Он появляется в вызове σ (выбор/ограничение). Вызов выводит строки, которые делают значение отношения аргумента истинным и делают условие (предикат) истинным. Т.е. строки, которые делают И (конъюнкцию) двух предикатов истинными. Т.е. в его вводятся элементы, которые делают условие истинным. Все, что связано с общим результатом, заключается в том, что он вычисляет что-то на этом пути.

Вы можете перевести ваш запрос на естественный язык. Несмотря на то, что вы написал, он (неофициально) переводит, если с естественного языка. Это будет получится, чтобы говорить о максимуме.Например, температура в строках, которые удовлетворяют:

-- temp ← ∏works.person_name(σp(works⨯ρd(works))) 
FOR SOME works.company_name, works.salary, 
    d.person_name, d.company_name, d.salary: 
     person [works.person_name] works for company [works.company_name] 
      for salary [works.salary] 
    AND person [d.person_name] works for company [d.company_name] 
      for salary [d.salary] 
    AND [works.salary] <= [d.salary] 
    AND ... 

Это строка, где человек [works.person_name] Работа для компании [works.company_name] для зарплаты [works.salary] и человек [d.person_name] Работа для компании [ d.company_name] для некоторой зарплаты [d.salary] AND [works.salary] < = [d.salary] AND ... для некоторых значений для атрибутов, отличных от works.person_name. Таким образом, это список людей, в которых есть еще один (≠) человек, имеющий как минимум большую зарплату в Small Bank Corporation.

(Ваш запрос будет проще, если вы проигнорируете имена людей и просто попросите пары людей, где работник имеет меньшую зарплату, чем d-человек. Если их зарплата не равна вашей, тогда они не вы .)