2

我正在做一個測試考試,我已經停留在一個特定的查詢中,在它的SQL代碼,關係代數和元組關係演算中。SQL查詢(在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中可用但不在MySQL中的函數,如EXCEPT,INTERSECT

FROM條款

由於無子查詢的說,它會如果有可能爲SQL,關係代數和元組關係演算提供的答案是極大的讚賞。這些問題阻礙了我。

在此先感謝!

回答

2
-- 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是這類操作的術語。

順便說一句:city表的複合(城市,州)主鍵只是在那裏混淆你。通常,您可以使用數字(代理)city_id作爲城市表的主鍵,並將其用作branches表中的外鍵。

+0

非常感謝!這非常有幫助!最後我明白瞭如何在「純」SQL編程中實現分割! – Cenderze

3

這是SQL Server語法,因爲我沒有MySQL或PostgreSQL的,但應該給你的想法:

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子句。

+0

我已經開始SQL小提琴的問題,並確認您的答案適用於SQL Server http://sqlfiddle.com/#!3/48e48和PostgreSQL但不適用於MySql。 – grahamj42

+0

@ grahamj42:什麼是MySql的WITH構造的等價物?是否有必要明確創建測試工作表? MySQL是否支持設置操作(即EXCEPT操作符)? –

+0

T認爲有必要創建表格,這就是SQL小提琴在回答這樣的問題時可以爲您做的事情。 – grahamj42