2

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

查询状态:查找包含关系中列出的每种类型的分支的 (city,state) 对Branch

在哪里Branch

Branch_ID (Primary key)
Branch_City
Branch_State
Branch_Type

和城市是:

City_Name (Primary key)
State_Name (Primary key)
Population

和分别是Branch_City和的Branch_State外键。City_NameState_Name

“规则”是不能使用聚合函数,例如COUNT,MAX等。

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

FROM子句中没有子查询

如前所述,如果可以为 SQL、关系代数和元组关系演算提供答案,将不胜感激。这些问题让我停滞不前。

提前致谢!

4

2 回答 2

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 子句中,因此这是合法的。它可以表示为左连接,但我认为这会将子查询移动到 FROM 子句中。

于 2013-03-23T10:35:09.903 回答
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
                )
        )
        ;

关系除法是此类操作的术语。

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

于 2013-03-23T13:06:44.220 回答