하위 쿼리가 SQL 쿼리에 표현력을 추가합니까?


29

SQL에 서브 쿼리가 필요합니까?

관계형 데이터베이스에 대해 구조화 된 쿼리 언어의 충분히 일반화 된 구현을 상상해보십시오. 표준 SQL SELECT문의 구조 는 실제로 이것이 의미가 있기 때문에 매우 중요하기 때문에 관계형 대수에 직접 호소하지는 않지만 표현식 형식에 적절한 제한을 두어 이러한 용어로 프레임을 구성 할 수 있습니다.

중 SQL SELECT쿼리는 일반적으로 투영합니다 (구성 SELECT부품)의 몇 개의 JOIN동작합니다 ( JOIN일부), 몇 개의 SELECTION 동작 (SQL에서, WHERE절), 그리고 설정 와이즈 (연산 UNION, EXCEPT, INTERSECT등), 다른 이어 SQL SELECT쿼리

결합되는 테이블은 계산 된 계산 결과 일 수 있습니다. 다시 말해, 다음과 같은 진술을 할 수 있습니다.

SELECT t1.name, t2.address
  FROM table1 AS t1 
  JOIN (SELECT id, address 
          FROM table2 AS t3 
         WHERE t3.id = t1.id) AS t2
 WHERE t1.salary > 50,000;

계산 된 테이블을 SQL 쿼리의 일부로 하위 쿼리라고합니다. 위의 예에서 두 번째 (들여 쓰기) SELECT는 하위 쿼리입니다.

하위 쿼리를 사용하지 않는 방식으로 모든 SQL 쿼리를 작성할 수 있습니까? 위의 예는 다음과 같습니다.

SELECT t1.name, t2.address
  FROM table1 AS t1 
  JOIN table2 AS t2
    ON t1.id = t2.id
 WHERE t1.salary > 50,000;

이 예제는 다소 의심 스럽거나 사소한 것이지만 동등한 표현을 복구하기 위해 훨씬 더 많은 노력이 필요할 수 있습니다. 즉, 모든 SQL 쿼리에 대한 경우입니다 서브 쿼리와 쿼리의 존재 부질없는을하도록 와 동일한 기본 테이블에 대한 동일한 결과를 보장됩니다? SQL 쿼리를 다음 형식으로 제한하겠습니다.qqqq

SELECT <attribute>,
      ...,
      <attribute>
 FROM <a table, not a subquery>
 JOIN <a table, not a subquery>
  ...
 JOIN <a table, not a subquery>
WHERE <condition>
  AND <condition>
  ...
  AND <condition>

UNION
 -or-
EXCEPT
 -or-
<similar>

SELECT ...

등등. 왼쪽 및 오른쪽 외부 조인이 많이 추가되지는 않는다고 생각하지만 실수하면 언제든지 지적하십시오 ... 어쨌든 공정한 게임입니다. 집합 연산이 진행되는 한, 조합, 차이, 대칭 적 차이, 교차점 등 도움이되는 모든 것이 괜찮습니다. 모든 SQL 쿼리를 줄일 수있는 알려진 형식이 있습니까? 이 중 하위 쿼리를 제거하는 것이 있습니까? 또는 하위 쿼리가없는 동등한 쿼리가없는 인스턴스가 있습니까? 참조는 감사합니다 ... 또는 그들이 요구하거나 필요하지 않다는 증거 (증거에 의한)는 환상적입니다. 고마워, 그리고 이것이 내가 고통스럽게 무지한 유명한 (또는 사소한) 결과라면 죄송합니다.


5
내 직감은 집계 된 값이 필요하지 않은 한 항상 모든 것을 함께 결합하고 선택할 수 있다고 말합니다. 열 평균보다 큰 값을 가진 모든 항목을 선택하려면 먼저 averge를 계산해야하므로 하위 쿼리가 필요합니다.
라파엘

@Raphael 나는 당신이 집계 된 값을 할 수도 있다고 확신합니다. 자기 조인과 그룹별로 더 많은 것을 수행해야합니다 (지수 적으로는 커지지 만 여전히 가능합니다). 그래도 당신이 그렇게 모든 것을 할 수 있다는 것을 공식적으로 증명 한 방법을 모르겠습니다.
Kevin

@Kevin 필요한 작업 수가 행 수에 의존하지 않습니까? 우리는 그것을 가질 수 없기 때문에, 우리는 할 수 있습니까?
Raphael

1
하위 쿼리가 필요한 일반적인 예는 중복 수를 계산하는 것 select count(*) from (select id from sometable group by id having count(*)>1) d입니다. 그것이 포함되어 있기 때문에 group by나는 이것을 대답으로 넣지 않았습니다.
Mark Hurd

일반 SQL에서 BTW AFAIK ON절은 JOINs에 필요 하지만 쉼표로만 크로스 제품을 얻을 수 있습니다.
Mark Hurd

답변:


9

용어 혼동이 있습니다. 괄호 안의 쿼리 블록

SELECT t1.name, t2.address
  FROM table1 
  JOIN (SELECT id, address 
          FROM table2 AS t3 
         WHERE t3.id = t1.id) 

내부보기 라고 합니다 . 하위 쿼리 중 하나 WHERE 또는 SELECT 절, 예를 들면 내에서 쿼리 블록

select deptno from dept
where 3 < (select count(1) from emp 
           where dept.deptno=emp.deptno)

두 경우 모두 내부보기 또는 하위 쿼리를 "플랫"프로젝트 제한 조인으로 중첩 해제 할 수 있습니다. 집계와 연관된 하위 쿼리는 그룹화를 통해 내부보기로 중첩 해제 된 다음 플랫 쿼리로 중첩 해제됩니다.

select deptno from dept d
    where 3 < (select avg(sal) from emp e
               where d.deptno=e.deptno)

select d.deptno from dept d, ( 
    select deptno from emp e
    group by deptno
    having avg(sal) > 3
) where d.deptno=e.deptno

select d.deptno from dept d, emp e
where d.deptno=e.deptno 
group by d.deptno
having avg(sal) > 3

쿼리 최적화를위한 대수 규칙에 관해서는, 관계 대수는에 axiomatized 것으로 알려져있다 관계형 격자 입증 된 바와 같이 쿼리 변환을 간단하게 여기거기를 .


궁금합니다. 평균보다 높은 값을 가진 모든 항목을 선택하는 등 일부 필드 평균을 사용하는 쿼리의 예를 추가 할 수 있습니까? 평평한 후에 어떻게 보일지 분명하지 않습니다.
Raphael

16

진술을 관계형 대수로 번역하려면 다음과 같이 묻습니다.

를 다시 쓸 수 있습니까 ?σ A ( σ B ( A B ) )σA(A)σB(B)σA(σB(AB))

( 가 선택되고 가 결합되는 위치)σ

대답은 "예"이며 표준 쿼리 최적화입니다. 솔직히 말해서, 이것을 물음 구걸하지 않는 방법으로 증명하는 방법을 모르겠습니다. 단지 선택과 가입의 속성 일뿐입니다. 그러나 원하는 많은 중첩 쿼리 계층을 추가하도록 유도 적으로 주장 할 수 있습니다.

또한 다음과 같이 요청할 수 있습니다.

수있는 모든 같이 쓸 조인 시퀀스 [달리 말하자면, ]?( A B ) ( C D )ABC(AB)(CD)

조인이 연관되어 있기 때문에 다시 대답은 그렇습니다. 투영에 대해서도 비슷한 진술을 할 수 있습니다.

"평면화"할 수 없다고 생각되는 주목할만한 "하위 쿼리"유형 중 하나는 with입니다. 이것을 보는 한 가지 방법은 with명령문 이 있으면 재귀 함수를 가질 수 있으며 하위 쿼리를 사용하지 않고는 작성할 수 없다는 점입니다.

요약하자면, 언급 한 특정 사례에서 아니요, SQL에는 하위 쿼리가 필요하지 않으며 귀납적으로 증명할 수 있습니다. 그러나 일반적으로 하위 쿼리가 필요한 기능이 있습니다.


를 통한 재귀 동작 with은 SQL : 1999에 도입되었으며 결과 언어를 엄격하게 표현합니다.
András Salamon

1

"하위 쿼리가 SQL 쿼리에 표현력을 추가합니까?"

그들은 적어도 SQL 언어로 EXCEPT가 도입되기 전에 수행했습니다.

EXCEPT가 도입되기 전에는 하위 쿼리에 의존하지 않고 SQL에서 관계형 차이 또는 반차를 표현할 방법이 없었습니다.

요즘 "관계형"대수학의 모든 "일반적인"기본 연산자는 하위 쿼리없이 표현 될 수 있습니다.

NATURAL JOIN은 NATURAL JOIN을 통해 수행하거나
UNION ON UNION을 통해 UNION
MINUS를 통해 수행 할 수 있습니다. EXCEPT
PROJECT / RENAME / EXTEND를 통해 수행 할 수 있습니다. SELECT
RESTRICT을 통해
수행
할 수 있습니다. 재귀 WITH를 통해 수행

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.