SQL查询(在SQL中,关系代数和元组关系演算)

时间:2013-03-23 09:24:07

标签: sql postgresql relational-algebra relational-division tuple-relational-calculus

我正在做一个测试考试,我在SQL代码,关系代数和元组关系演算中遇到了一个特定的查询。

查询说明: 找到(城市,州)对,其中包含Branch中列出的每种类型的分支 关系。

Branch的位置:

Branch_ID (Primary key)
Branch_City
Branch_State
Branch_Type

和城市是:

City_Name (Primary key)
State_Name (Primary key)
Population

Branch_CityBranch_State分别是City_NameState_Name的外键。

“规则”是指使用COUNTMAX等集合函数。

MySQL和PostgreSQL必须“理解”查询,但是可以使用PostgreSQL中可用的EXCEPTINTERSECT等函数,但不能在MySQL中使用。

FROM子句

中没有子查询

如上所述,如果能为sQL,关系代数和元组关系演算提供答案,我们将不胜感激。那些问题使我陷入困境。

提前致谢!

2 个答案:

答案 0 :(得分:3)

这是SQL Server语法,因为我没有MySql或PostGresSQL,但应该给你这个想法:

with branches as (
  select * from ( values
    ('Perth',1),
    ('Toronto',1), ('Toronto',2), ('Toronto',3),
    ('Hamilton',2), ('Hamilton',3)
  ) branches(City,  Branch_Type)
)

  select distinct
    City
  from branches
except
  select distinct 
    b.City
  from branches t 
  cross join branches b 
  left join branches b2 on b2.Branch_Type = t.Branch_Type and b2.City = b.City
  where b2.Branch_Type is null

我已经将它调整到最低限度,以展示必要的设置操作。

查询的上半部分返回所有三个城市;下半场只返回汉密尔顿和珀斯;这样整个查询只返回多伦多。

我在30年内没有使用过关系代数或关系微积分,但在这些方言中表达上述查询只是一种翻译练习。

更新 - 适用于MySQL:

with branches as (
  select * from ( values
    ('Perth',1),
    ('Toronto',1), ('Toronto',2), ('Toronto',3),
    ('Hamilton',2), ('Hamilton',3)
  ) branches(City,  Branch_Type)
)

select distinct
  City
from branches
where City not in (
  select distinct 
    b.City
  from branches t 
  cross join branches b 
  left join branches b2 on b2.Branch_Type = t.Branch_Type and b2.City = b.City
  where b2.Branch_Type is null
  )

由于子查询在WHERE子句而不是FROM子句中,因此该shold是合法的。它可以表示为左连接,但我认为将子查询移动到FROM子句中。

答案 1 :(得分:3)

-- The query states: Find the (city,state) pairs which house a branch of every type which is listed in the Branch relation.
--                                               ((((                    ^^^^^ ^^^^    ))
-- This is equivalent to: Find cities for which "There does NOT EXIST a branchType that is NOT PRESENT in this City"
-- This leads to the double "NOT EXISTS (NOT EXISTS())" solution to relational devision.::
SELECT  * -- city,state
FROM city c
WHERE NOT EXISTS (
        -- find a branchtype that is not present in our city
        SELECT * FROM Branch b
        WHERE NOT EXISTS (
                -- same city for this  branchtype
                SELECT * FROM Branch nx
                WHERE nx.Branch_City = c.City_Name AND nx.Branch_State = c.State_Name
                AND nx.Branch_Type = b.Branch_Type
                )
        )
        ;

Relational division是此类操作的术语。

BTW:city表的复合(城市,州)主键只会让您感到困惑。通常,您将使用数字(代理)city_id作为城市表的主键,并将其用作branches表中的外键。