SQL 스펙에 EXISTS에서 GROUP BY가 필요합니까 ()


11

Microsoft는 현재이 구문을 허용합니다.

SELECT *
FROM ( VALUES (1) ) AS g(x)
WHERE EXISTS (
  SELECT *
  FROM ( VALUES (1),(1) )
    AS t(x)
  WHERE g.x = t.x
  HAVING count(*) > 1
);

어떤이 있음을주의 GROUP BYEXISTS절은 그 유효 ANSI SQL이다. 아니면 단순히 구현 세부 사항을 노출하는 것입니까?

참고로 PostgreSQL에서는 이와 동일한 구문이 허용되지 않습니다.

오류 : "tx"열이 GROUP BY 절에 나타나거나 집계 함수에 사용되어야합니다.

그러나이 구문은 허용됩니다.

SELECT *
FROM ( VALUES (1) ) AS g(x)
WHERE EXISTS (
  SELECT 1  -- This changed from the first query
  FROM ( VALUES (1),(1) )
    AS t(x)
  WHERE g.x = t.x
  HAVING count(*) > 1
);

그리고이 구문은 허용됩니다.

SELECT *
FROM ( VALUES (1) ) AS g(x)
WHERE EXISTS (
  SELECT *
  FROM ( VALUES (1),(1) )
    AS t(x)
  WHERE g.x = t.x
  GROUP BY t.x  -- This changed from the first query
  HAVING count(*) > 1
);

채팅에서 @ErikE와의 대화 에서 질문이 발생합니다.

답변:


11

SQL 2011 사양에서 찾았습니다 ...

는 IF <select list>"*"를 단순히 포함되는 <table subquery>즉시에 포함되어 그 <exists predicate>후,이 <select list>(A)에 상당 <value expression>임의하다 <literal>.

이것은 *이 문맥에서 임의의 리터럴과 동등하지 않음으로써 실제로 PostgreSQL이 사양을 위반한다는 것을 확인 합니다.

이 문제는

SELECT *
FROM ( VALUES (1),(2),(3) ) AS t(x)
HAVING count(*) > 1

두 데이터베이스 모두 거부합니다.

PostgreSQL,

오류 : "tx"열이 GROUP BY 절에 나타나거나 집계 함수에 사용되어야합니다.

SQL Server,

'tx'열은 집계 함수 또는 GROUP BY 절에 포함되지 않으므로 선택 목록에서 유효하지 않습니다.

PostgreSQL에서이 버그가 지속되는 이유

irc.freenode.net/#PostgreSQL의 RhodiumToad에게 감사의 말을 전합니다. 그는 또한이 상황을 해결하는 데 어려움을 지적

20:33 <RhodiumToad> 하나의 문제는 pg에서 당신이 할 수 있다는 것입니다 (func () from ...

SRF는 세트 리턴 기능입니다.

PostgreSQL에서 예를 들어 SRF를 사용하여 1-10의 시리즈를 생성 할 수 있습니다 ( generate_series핵심에 있음)

SELECT * FROM generate_series(1,10); 

우리도 마찬가지로 여기에 넣을 수 있습니다.

SELECT generate_series(1,10);

둘 중 하나가 함께 교차 결합 (카테 시안 곱)을 제공합니다.

SELECT generate_series(1,10), generate_series(1,2);

그러나 그중 하나가 0 행을 반환하면 아무것도 얻지 못합니다.

SELECT * FROM ( VALUES (1) ) AS t(x)
CROSS JOIN ( SELECT 1 LIMIT 0 ) AS g;

그리고 이것이 이것을 완전히 최적화하는 문제입니다. EXIST 문 내부의 선택 목록에 SRF를 사용하여 0 행을 리턴하고 EXISTS를 강제로 거짓으로 평가할 수 있습니다.

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