2010-07-02 6 views
13

Bạn không thể (không được) đặt các số không tổng hợp vào dòng SELECT của truy vấn GROUP BY.Tôi có thể sử dụng các cột không tổng hợp với nhóm không?

Tuy nhiên, tôi muốn truy cập vào một trong những tập hợp không được kết hợp với giá thầu CPC Trong tiếng Anh đơn giản, tôi muốn một bảng có id cũ nhất của mỗi loại.

CREATE TABLE stuff (
    id int, 
    kind int, 
    age int 
); 

Truy vấn này mang lại cho tôi những thông tin tôi sau:

SELECT kind, MAX(age) 
FROM stuff 
GROUP BY kind; 

Nhưng nó không phải theo hình thức hữu ích nhất. Tôi thực sự muốn id được liên kết với mỗi hàng để tôi có thể sử dụng nó trong các truy vấn sau này.

Tôi đang tìm một cái gì đó như thế này:

SELECT id, kind, MAX(age) 
FROM stuff 
GROUP BY kind; 

Đó kết quả đầu ra này:

SELECT stuff.* 
FROM 
    stuff, 
    (SELECT kind, MAX(age) 
    FROM stuff 
    GROUP BY kind) maxes 
WHERE 
    stuff.kind = maxes.kind AND 
    stuff.age = maxes.age 

Nó thực sự có vẻ như không nên có đi để có được thông tin này mà không cần phải tham gia. Tôi chỉ cần các công cụ SQL để nhớ các cột khác khi nó tính toán tối đa.

+1

Đẹp, chắc chắn bạn sẽ cần để tham gia để có được những gì bạn muốn. Nó sẽ được mát mẻ nếu có một số cách để nói "kéo giá trị từ hàng này, bạn chỉ cần lấy tối đa từ" nhưng không có một tham gia không phải là kiến ​​thức của tôi. – heisenberg

+2

Có thể không chỉ có một id với độ tuổi tối đa. Mà một trong những nên được trả lại? Hoặc bạn sẽ nhận được một cho mỗi hàng? – Blorgbeard

+0

Hoặc trường hợp bạn có nhiều tập hợp lựa chọn các hàng khác nhau, sẽ cần phải có một số loại đường cú pháp cho phép bạn cho biết tổng hợp từng trường cần được liên kết với. – heisenberg

Trả lời

10

Bạn không thể lấy Id của hàng MAX tìm thấy, vì không thể chỉ có một id có độ tuổi tối đa.

1

Bạn phải tham gia vì hàm tổng hợp tối đa truy lục nhiều hàng và chọn giá thầu CPC Vì vậy, bạn cần tham gia để chọn một chức năng mà hàm agregate đã tìm thấy.

Để đặt theo cách khác, bạn mong đợi truy vấn sẽ hoạt động như thế nào nếu bạn thay thế tối đa bằng tổng?

Kết nối bên trong có thể hiệu quả hơn truy vấn phụ của bạn.

4

Bạn không thể (không được) đặt các số không tổng hợp vào dòng SELECT của truy vấn GROUP BY.

Bạn có thể và phải xác định những gì bạn đang nhóm theo cho hàm tổng hợp để trả về kết quả chính xác.

MySQL (và SQLite) quyết định trong sự khôn ngoan vô hạn của chúng rằng chúng sẽ chống lại spec và cho phép truy vấn chấp nhận các mệnh đề GROUP BY thiếu cột được trích dẫn trong CHỌN - nó có hiệu quả làm cho các truy vấn này không di động.

Thực sự có vẻ như cần có thông tin này mà không cần tham gia.

Không truy cập vào các chức năng phân tích/xếp hạng/cửa sổ mà MySQL không hỗ trợ, tự tham gia vào chế độ xem bảng/nội tuyến có nguồn gốc là phương tiện di động hiệu quả nhất.

+0

Bạn đã viết: "Bạn có thể, và phải, xác định những gì bạn đang nhóm theo cho hàm tổng hợp để trả lại kết quả chính xác." Có vẻ như bạn đang phản hồi nghịch đảo của những gì @deft_code hỏi. Ông đã nói về một trường hợp mà GROUP BY được xác định nhưng có * không có tổng hợp *. – Quuxplusone

1

Tôi nghĩ rằng thật sự hấp dẫn khi yêu cầu hệ thống giải quyết vấn đề trong một lần thay vì phải thực hiện công việc hai lần (tìm giá trị tối đa và tìm id tương ứng). Bạn có thể làm bằng CONCAT (như đề xuất trong Naktibalda refered bài viết), không chắc chắn đó sẽ là effeciant hơn

SELECT MAX(CONCAT(LPAD(age, 10, '0'), '-', id) 
FROM STUFF1 
GROUP BY kind; 

nên làm việc, bạn phải chia câu trả lời để có được tuổi và id. (Đó thực sự là xấu xí mặc dù)

+0

'-' là thêm dấu tách giữa độ tuổi và id, không phải phép trừ – mb14

2

Trong cơ sở dữ liệu gần đây bạn có thể sử dụng sum() trên (parition bởi ...) để giải quyết vấn đề này:

select id, kind, age as max_age from (
    select id, kind, age, max(age) over (partition by kind) as mage 
    from table) 
where age = mage 

này sau đó có thể đơn qua