这是数据库,粗体主键。
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实体?
答案 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人少的人。如果他们的工资不等于你的工资那么他们就不是你。 )