2

SQL 쿼리, 관계형 대수 및 튜플 관계형 수학에서 특정 쿼리를 사용하지 않고 테스트를 수행하고 있습니다.SQL 쿼리 (SQL, 관계형 대수 및 튜플 관계 계산법)

쿼리 상태 : 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에 외래 키 Branch

.

"규칙"은 COUNT, MAX과 같은 집계 함수가이 아닐 수 있습니다.

쿼리는 MySQL과 PostgreSQL에서 "이해해야"하지만 EXCEPT, INTERSECT 같은 함수는 PostgreSQL에서 사용할 수 있지만 MySQL에서는 사용할 수 없습니다. 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은 이러한 유형의 작업에 대한 용어입니다.

BTW : city 테이블의 복합 (도시, 주) 기본 키는 단지 혼동을 줄 수 있습니다.일반적으로 숫자 (대용) city_id을 도시 테이블의 기본 키로 사용하고 branches 테이블의 외래 키로 사용합니다.

+0

고맙습니다! 이것은 매우 도움이되었습니다! 마지막으로 "순수한"SQL 프로그래밍에서 나누기가 어떻게 구현되는지 이해합니다! – Cenderze

3

이것은 내가 MySQL의 또는 포스트그레스 SQL이 없기 때문에, SQL 서버 구문이지만, 당신에게 아이디어를 제공해야합니다입니다 : 내가 필요한 설정 작업을 보여주기 위해 최소한으로 내려 손질 한

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 

합니다.

쿼리의 상위 절반은 세 도시를 모두 반환합니다. 후반은 Hamilton과 Perth 만 반환합니다. 그래서 전체 쿼리는 토론토 만 반환합니다.

저는 30 년 동안 관계형 대수학이나 관계형 미적분을 사용하지 않았지만, 위의 질의를 해당 방언으로 exxpressing하는 것은 단순히 번역 연습입니다.

업데이트 - 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 Fiddle을 이미 시작했으며 SQL Server http://sqlfiddle.com/#!3/48e48 및 PostgreSQL에 대한 대답은 확인했지만 MySql에 대한 대답은 아닌지 확인합니다. – grahamj42

+0

@ grahamj42 : WITH 구조에 해당하는 MySql은 무엇입니까? 테스트를 위해 작업 테이블을 명시 적으로 작성해야합니까? MySQL이 집합 연산 (예 : EXCEPT 연산자)을 지원합니까? –

+0

테이블을 만들 필요가 있다고 생각합니다. SQL Fiddle이 이와 같은 질문에 대답 할 때 할 수있는 것입니다. – grahamj42