Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

Có thể sử dụng GROUP BY với các biến ràng buộc không?

Tôi khuyên bạn nên viết lại câu lệnh để chỉ có một đối số ràng buộc. Cách tiếp cận này hơi tệ, nhưng trả về tập kết quả:

select max(col1) 
     , f_col2
  from (
         select col1
              , f(? ,col2) as f_col2 
           from t
       )
 group
    by f_col2

Câu lệnh được viết lại này chỉ có một tham chiếu đến một đối số ràng buộc duy nhất, vì vậy bây giờ DBMS thấy các biểu thức trong mệnh đề GROUP BY và danh sách SELECT giống hệt nhau.

HTH

[CHỈNH SỬA]

(Tôi ước có một cách hay hơn, đây là lý do tại sao tôi thích cách tiếp cận đối số ràng buộc có tên mà Oracle sử dụng. Với trình điều khiển Perl DBI, các đối số vị trí được chuyển đổi thành các đối số được đặt tên trong câu lệnh thực sự được gửi đến Oracle.)

Tôi không thấy vấn đề lúc đầu, tôi không hiểu câu hỏi ban đầu. (Rõ ràng là một số người khác cũng đã bỏ qua nó.) Nhưng sau khi chạy một số trường hợp thử nghiệm, tôi nhận ra rằng vấn đề là gì, câu hỏi đang hoạt động là gì.

Hãy để tôi xem liệu tôi có thể nêu vấn đề:làm thế nào để hai đối số ràng buộc (vị trí) riêng biệt được xử lý (bởi DBMS) như thể nó là hai tham chiếu đến cùng một đối số ràng buộc (được đặt tên).

DBMS đang mong đợi biểu thức trong GROUP BY khớp với biểu thức trong danh sách SELECT. Nhưng hai biểu thức được coi là KHÁC NHAU ngay cả khi các biểu thức giống hệt nhau, khi sự khác biệt duy nhất là mỗi biểu thức tham chiếu đến một biến ràng buộc khác nhau. (Chúng tôi có thể chứng minh một số trường hợp thử nghiệm mà ít nhất một số DBMS sẽ cho phép, nhưng có nhiều trường hợp chung hơn sẽ dẫn đến một ngoại lệ.)

Tại thời điểm này, câu trả lời ngắn gọn là, điều đó khiến tôi bối rối. Đề xuất mà tôi có (có thể không phải là câu trả lời thực sự cho câu hỏi ban đầu) là cấu trúc lại truy vấn.

[/ CHỈNH SỬA]

Tôi có thể cung cấp thêm chi tiết nếu cách tiếp cận này không hoạt động hoặc nếu bạn gặp một số vấn đề khác khi tìm ra nó. Hoặc nếu có vấn đề với hiệu suất (tôi có thể thấy trình tối ưu hóa chọn một kế hoạch khác cho truy vấn được viết lại, mặc dù nó trả về tập kết quả được chỉ định. Để kiểm tra thêm, chúng tôi thực sự cần biết DBMS, trình điều khiển nào, thống kê, v.v.)

CHỈNH SỬA (tám năm rưỡi sau)

Một nỗ lực khác để viết lại truy vấn. Một lần nữa, giải pháp duy nhất tôi đưa ra là truy vấn với một trình giữ chỗ ràng buộc. Lần này, chúng tôi gắn nó vào một dạng xem nội tuyến trả về một hàng duy nhất và nối nó với t. Tôi có thể thấy nó đang làm gì; Tôi không chắc trình tối ưu hóa Oracle sẽ thấy điều này như thế nào. Chúng tôi có thể muốn (hoặc cần) thực hiện một chuyển đổi rõ ràng, ví dụ:TO_NUMBER(?) AS param , TO_DATE(?,'...') AS param , TO_CHAR(?) AS param , tùy thuộc vào kiểu dữ liệu của tham số liên kết và kiểu dữ liệu mà chúng tôi muốn được trả về từ chế độ xem.)

Đây là cách tôi sẽ làm điều đó trong MySQL. Truy vấn ban đầu trong câu trả lời của tôi thực hiện thao tác nối bên trong dạng xem nội tuyến (MySQL bảng dẫn xuất ). Và chúng tôi muốn tránh hiện thực hóa một bảng dẫn xuất hughjass nếu chúng tôi có thể tránh nó. Sau đó, một lần nữa, MySQL có thể sẽ để truy vấn ban đầu trượt miễn là sql_mode không bao gồm ONLY_FULL_GROUP_BY . MySQL cũng sẽ cho phép chúng tôi loại bỏ FROM DUAL )

  SELECT MAX(t.col1)
       , f( v.param ,t.col2)
    FROM t
   CROSS
    JOIN ( SELECT ? AS param FROM DUAL) v
   GROUP
      BY f( v.param ,t.col2)

Theo câu trả lời từ MadusankaD, trong vòng tám năm qua, Oracle đã bổ sung hỗ trợ để sử dụng lại các tham số ràng buộc được đặt tên tương tự trong trình điều khiển JDBC và giữ lại tính tương đương. (Tôi chưa thử nghiệm điều đó, nhưng nếu điều đó hoạt động ngay bây giờ, thì thật tuyệt.)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. CHÈN Đường dẫn Trực tiếp Oracle

  2. Làm thế nào để thoát khỏi cột LOB trống nhưng rất lớn?

  3. Có thể xảy ra bế tắc với cùng một phương thức truy cập không?

  4. Tại sao chúng ta không thể thực thi thủ tục được lưu trữ trong câu lệnh select trong oracle? có lý do mạnh mẽ nào không?

  5. Chọn từ nhiều phân vùng cùng một lúc