为什么查询超过每个vs小于某些实体的实体更难?

时间:2015-12-05 10:41:57

标签: sql database relational relational-algebra

这是数据库,粗体主键。

  • works ( person_name , company_name, salary)

假设我们遇到这个问题:

查找收入超过Small Bank Corporation每位员工的所有员工的姓名。

建议的解决方案:

我们无法轻易计算出收入超过Small Bank Corporation每位员工的员工数量,但我们可以计算出收入低于Small Bank Corporation部分员工的员工数量。我们从所有员工的集合中减去这个集合。注意小于或等于我们删除具有相同名称的记录。

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

其中p是

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

然后答案是:

∏person_name(works) − temp

为什么我们不能轻易计算出收入超过Small Bank Corporation每位员工的人数?为什么我们可以轻松计算出收入较少的人群?我不明白这一点。 work.salary< = d.salary到底做了什么?它是否通过所有d.salary实体为每个works.salary实体循环,并查看它是否为< =对于所有d.salary实体?

2 个答案:

答案 0 :(得分:2)

可以很容易地表达查询:

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

答案 1 :(得分:1)

  

我们无法轻易计算出收入超过的员工   小银行公司的每个员工,但我们可以计算该组   收入低于Small Bank员工的员工数量   公司。

并不是产生差异的不平等。 (你可以通过在σ中更改它们来看到这一点。)这是FOR EVERY / ALL vs FOR SOME。

谓词是一个真或假的填充(命名)空白语句。

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

请注意,名称及其属性是谓词的简写版本。我们将关系变量的谓词,常量或表达式称为含义

假设关系表达式e& f保存构成谓词表达式E&的行。 F为真(分别)。代数运算符的设计是为了:

R 保持满足R(R.X,...)的行 ρS(e with attributes R.X ) 保持满足E的行,其中R.X由S.X替换 e⨯f 保持满足E和F的行 e-f 保持满足E和NOT F的行 eUf 保持满足E或F的行 σ condition (e) 保持满足E AND 条件的行 πA(e) 保持满足FOR SOME 所有属性的行,但A :E

恰恰相反,对于每一个小的变化,意义都会发生微小的变化。请注意,该列表不包含表达式~(e)(“补码”),该表达式包含NOT E的行,即e中不是的行。因为(通常)很多行计算是不切实际的。但事实证明,如果我们从不希望这些行作为查询结果(我们通常不会),那么我们可以使用其他运算符重写。对于所有答:E表示不适用于某些A:不是E.所以涉及FOR ALL的查询很复杂,我们不能(通常)在外面有FORALL。原始意思并不复杂,但我们必须将其重新排列为由复杂关系表达式计算的复杂措辞。

所以答案是,它发生了FOR SOME A:E很容易计算和可视化的关系,但FOR ALL A:E使用廉价运算符的复杂调用以便宜地计算并且不是人类的关系 - 显然重新安排e。

(使用FOR ALL的各种特殊情况直接转换为各种“除法”运算符的简单调用。但是特殊情况没有简单的含义!事实证明,表达FOR ALL查询更简单关系子集运算符。)

(请参阅我的答案及其问题here重新预测&代数和here重新编译。)

  

works.salary< = d.salary到底做了什么?它是否为每一个循环   通过所有d.salary实体work.salary实体并查看它是否   是< =对于所有d.salary实体?

出现在σ调用(选择/限制)中。该调用输出使参数关系值为true并使条件(谓词)为真的行。即使两个谓词的AND(连接)为真的行。即它的输入中的roews使条件成立。所有与整体结果有关的是它在整个过程中计算出一些东西。

您可以将查询翻译成自然语言。虽然你的方式是通过(非正式地)翻译来自自然语言。这将结果谈论最大值。例如,temp是满足以下条件的行:

-- 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]&lt; = [d.salary] AND ...,用于除works.person_name以外的属性的某些值。因此,这是一个人员名单,其中存在一些其他(≠)人,其薪水至少与Small Bank Corporation一样大。

(如果你忽略了人名,你的查询会更简单,只是要求工作人员工资比d人少的人。如果他们的工资不等于你的工资那么他们就不是你。 )