SQL Spec có yêu cầu NHÓM THEO trong EXISTS () không


11

Microsoft hiện cho phép cú pháp này.

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
);

Lưu ý rằng không có GROUP BYtrong EXISTSmệnh đề, đó là ANSI SQL hợp lệ. Hoặc nó chỉ đơn thuần là phơi bày một chi tiết thực hiện.

Để tham khảo, cú pháp tương tự này không được phép trong PostgreSQL.

LRI: cột "tx" phải xuất hiện trong mệnh đề GROUP BY hoặc được sử dụng trong hàm tổng hợp

Nhưng cú pháp này được cho phép ..

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
);

Và cú pháp này được cho phép.

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
);

Câu hỏi phát sinh từ một cuộc trò chuyện với @ErikE trong trò chuyện

Câu trả lời:


11

Tôi đã tìm thấy nó trong đặc tả SQL 2011 ...

Nếu đơn vị <select list>* * chỉ đơn giản được chứa trong một <table subquery>cái mà ngay lập tức được chứa trong một <exists predicate>, thì cái đó <select list>tương đương với cái <value expression>đó là tùy ý <literal>.

Điều này xác nhận rằng bằng cách *không tương đương với một nghĩa đen tùy ý trong bối cảnh này, thực tế là PostgreQuery phá vỡ thông số kỹ thuật.

Hãy nhớ rằng đây là một vấn đề khác biệt với

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

Mà cả hai cơ sở dữ liệu từ chối.

PostgreSQL,

LRI: cột "tx" phải xuất hiện trong mệnh đề GROUP BY hoặc được sử dụng trong hàm tổng hợp

Máy chủ SQL,

Cột 'tx' không hợp lệ trong danh sách chọn vì nó không có trong hàm tổng hợp hoặc mệnh đề GROUP BY.

Tại sao lỗi này vẫn tồn tại trong PostgreSQL

Cảm ơn đã đến RhodiumToad trên irc.freenode.net/#PostgreSQL vì sự giúp đỡ của anh ấy khi gặp sự cố này. Ông cũng chỉ ra những khó khăn trong việc giải quyết tình huống này

20:33 <RhodiumToad> một vấn đề là trong pg bạn có thể tồn tại (chọn func () từ ... trong đó func () là SRF có thể trả về 0 hàng

SRF là một hàm trả về được thiết lập.

Trong PostgreSQL, chúng ta có thể sử dụng SRF để tạo một chuỗi từ 1-10 ( generate_seriestrong lõi)

SELECT * FROM generate_series(1,10); 

Và, chúng tôi cũng có thể đặt nó ở đây.

SELECT generate_series(1,10);

Hai trong số họ cùng nhau cung cấp cho chúng tôi một liên kết chéo (sản phẩm cartesian)

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

Nhưng, nếu một trong hai hàng trả về 0, bạn không nhận được gì .. Thực tế giống như thế này

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

Và, đó là vấn đề với việc tối ưu hóa hoàn toàn điều này. Bạn có thể có SRF trong danh sách chọn bên trong câu lệnh EXIST trả về 0 hàng và buộc EXISTS đánh giá thành sai.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.