2011-01-06 57 views
32

Tôi cần một chút giúp đỡ thẳng ra một cái gì đó, tôi biết đó là một câu hỏi dễ dàng rất dễ dàng nhưng đó là một cái gì đó mà là hơi khó hiểu tôi trong SQL.GROUP BY/tổng hợp chức năng nhầm lẫn trong SQL

Truy vấn SQL này ném lỗi 'không phải là biểu tượng GROUP BY' trong Oracle. Tôi hiểu tại sao, như tôi biết rằng khi tôi nhóm theo một thuộc tính của một bộ dữ liệu, tôi không còn có thể truy cập vào bất kỳ thuộc tính nào khác.

SELECT * 
FROM order_details 
GROUP BY order_no 

Tuy nhiên cái này không làm việc

SELECT SUM(order_price) 
FROM order_details 
GROUP BY order_no 

Chỉ cần để bê tông hiểu biết của tôi về vấn đề này .... Giả sử rằng có nhiều bản ghi trong ORDER_DETAILS cho mỗi đơn hàng đó được thực hiện, một khi tôi nhóm tuples theo order_no, tôi vẫn có thể truy cập thuộc tính order_price cho từng tuple riêng lẻ trong nhóm, nhưng chỉ sử dụng một hàm tổng hợp?

Nói cách khác, các hàm tổng hợp khi được sử dụng trong mệnh đề SELECT có thể đi sâu vào nhóm để xem các thuộc tính 'ẩn', ở đó chỉ cần sử dụng 'SELECT order_no' sẽ phát sinh lỗi?

Cảm ơn sự giúp đỡ của bạn trong việc làm rõ điều này, tôi đã gặp khó khăn khi tìm câu trả lời cho câu hỏi cụ thể này trên Google.

Chris

Trả lời

34

Trong SQL tiêu chuẩn (nhưng không phải MySQL), khi bạn sử dụng GROUP BY, bạn phải liệt kê tất cả các cột kết quả mà không phải là uẩn trong mệnh đề GROUP BY. Vì vậy, nếu order_details có 6 cột, thì bạn phải liệt kê tất cả 6 cột (theo tên - bạn không thể sử dụng * trong mệnh đề GROUP BY hoặc ORDER BY) trong mệnh đề GROUP BY.

Bạn cũng có thể làm:

SELECT order_no, SUM(order_price) 
    FROM order_details 
GROUP BY order_no; 

Điều đó sẽ làm việc vì tất cả các cột không tổng hợp được liệt kê trong mệnh đề GROUP BY.

Bạn có thể làm một cái gì đó như:

SELECT order_no, order_price, MAX(order_item) 
    FROM order_details 
GROUP BY order_no, order_price; 

Truy vấn này là không thực sự có ý nghĩa (hoặc có lẽ hầu hết là không có ý nghĩa), nhưng nó sẽ 'làm việc'. Nó sẽ liệt kê từng kết hợp đơn đặt hàng và số đơn đặt hàng riêng biệt và sẽ cung cấp cho mục hàng tối đa (số) được liên kết với giá đó. Nếu tất cả các mục trong một đơn đặt hàng có giá riêng biệt, bạn sẽ kết thúc với các nhóm một hàng. OTOH, nếu có một số mặt hàng theo thứ tự ở cùng một mức giá (nói £ 0,99 mỗi), sau đó nó sẽ nhóm những người lại với nhau và trả lại số đơn đặt hàng tối đa ở mức giá đó. (Tôi giả định rằng bảng có khóa chính trên (order_no, order_item) trong đó mục đầu tiên theo thứ tự có order_item = 1, mục thứ hai là 2, v.v.)

+0

OK, vì vậy sau khi GROUP BY được thực hiện, tất cả các bộ dữ liệu riêng lẻ cho một đơn đặt hàng cụ thể vẫn có thể truy cập được bằng các hàm tổng hợp. Nghĩa là hàm SUM vẫn có thể truy cập thuộc tính order_price của mỗi bộ dữ liệu, mặc dù các bộ dữ liệu đó đã được nhóm lại với nhau bởi order_no? – Chris

+5

@ Chris: có, nhiều hơn hoặc ít hơn. Bạn có thể nghĩ rằng GROUP BY phân chia các hàng trong bảng thành các nhóm; mỗi nhóm có cùng một tập hợp các giá trị cho các cột được liệt kê trong mệnh đề GROUP BY. Các tập hợp sau đó hoạt động trên bất kỳ cột nào được chỉ định, với tổng hợp được tính toán trên các hàng trong nhóm. Kết quả sau đó bao gồm một hàng cho mỗi nhóm, với các giá trị cột GROUP BY cộng với các tập hợp liên quan. Hummm ... Tôi hy vọng điều đó rõ ràng ... –

+0

Đúng là nó đã hoàn toàn xóa nó đi xa như tôi có thể nói. Cảm ơn rất nhiều Jonathan và cảm ơn những người khác đã trả lời! – Chris

0

Để sử dụng nhóm theo mệnh đề, bạn phải đề cập tất cả các cột từ lựa chọn tuyên bố theo nhóm theo mệnh đề nhưng không phải cột từ hàm tổng hợp.

Để thực hiện việc này thay vì nhóm theo bạn có thể sử dụng phân đoạn theo mệnh đề bạn chỉ có thể sử dụng một cổng để nhóm làm phân đoạn theo.

bạn cũng có thể làm cho nó như là phân vùng bằng 1

0
SELECT * 
FROM order_details 
GROUP BY order_no 

Trong truy vấn ở trên, bạn sẽ chọn tất cả các cột vì lý do đó ném nó một lỗi không nhóm bởi một cái gì đó giống như .. để tránh điều đó, bạn phải đề cập đến tất cả các cột nào trong lựa chọn công bố tất cả các cột phải nằm trong nhóm quy định tại khoản ..

SELECT * 
    FROM order_details 
    GROUP BY order_no,order_details,etc 

vv nó có nghĩa là tất cả các cột từ bảng ORDER_DETAILS.