2013-01-23 28 views
7

Tôi đang rút ra một số cuộc hội thoại từ cơ sở dữ liệu của mình. Chúng được nhóm theo cột user_from.Nhận mục nhập mới nhất bằng cách sử dụng GROUP BY

Hiện tại, nó xuất ra thư cũ nhất. Tôi muốn nó hiển thị thông báo mới nhất.

Cách đơn giản nhất để thực hiện việc này là gì?

SELECT * 
FROM (`mail`) 
JOIN `users` ON `users`.`id` = `mail`.`user_from` 
JOIN `users_info` ON `users_info`.`user_id` = `mail`.`user_from` 
WHERE `user_to` = '1' 
GROUP BY `user_from` 
ORDER BY `mail`.`date` desc 

bảng tử

enter image description here

sử dụng bảng (đoạn)

enter image description here

Đây là mã làm việc hiện tại. Các SecretAgent gửi một thông điệp mới hơn hơn Mail từ cơ quan mà nó cần được hiển thị thay vì enter image description here

+4

@xQbert Tại sao ?, thư mới nhất là thư có ngày tối đa – Lamak

+0

Đoán thư đó là ID, tại sao bạn không đặt hàng bằng 'mail.id desc'? hoặc là những email được chèn từ những nơi khác nhau và id cao hơn không cần thiết là email mới nhất? – SERPRO

+0

Điều đó sẽ không thực hiện thủ thuật, nó vẫn chọn * cũ nhất * một –

Trả lời

4

MySQL là tiếc rất nhân hậu về nội dung của các GROUP BY khoản, trong đó sản xuất kết quả không đáng tin cậy, trừ khi bạn bao gồm tất cả các cột trong GROUP BY. Nó không bao giờ được đề xuất để SELECT * trong truy vấn tham gia, nhưng chúng tôi sẽ để lại điều đó ngay bây giờ. Những gì bạn cần làm là thực hiện một truy vấn phụ mà nhận được thông báo gần đây nhất cho người dùng theo ngày, tham gia vào phần còn lại của các cột.

SELECT 
    /* Don't actually do this. Be explicit about columns and assign aliases where their names collide */ 
    users.*, 
    users_info.*, 
    mail.* 
FROM 
    `users` 
    JOIN `mail` ON `users`.`id` = `mail`.`user_from` 
    JOIN `users_info` ON `users_info`.`user_id` = `mail`.`user_from` 
    /* Joined subquery gets most recent message from each user */ 
    JOIN (
    SELECT user_from, MAX(date) AS date 
    FROM mail 
    WHERE user_to = '1' 
    GROUP BY user_from 
    /* Joined back to the main mail table on user_from and date */ 
) most_recent ON mail.user_from = most_recent.user_from AND mail.date = most_recent.date 
    WHERE `user_to` =  '1' 

Sửa cập nhật để hiển thị tất cả người gửi gần đây nhất chứ không phải chỉ có một.

+0

Điều này dường như hoạt động khi chạy nó trong PHPMyAdmin. Bây giờ tôi sẽ đi sâu vào các tài liệu CodeIgniter và xem cách tôi có thể thực hiện công việc này bằng cách sử dụng Active Records. Cảm ơn bạn! :-) –

+0

+1 cho * không may *. Ném một bữa tiệc để kỷ niệm 100k? – Kermit

+0

@njk Chỉ hy vọng duy trì hoạt động - Tôi không trả lời quá nhiều nữa. một số dường như đã "nghỉ hưu" ở 100k. Tôi có thể mất 3 ngày ... –