2011-11-28 37 views
8

Tôi có hai bảng và tôi cố gắng tìm "bài đăng" có số điểm cao nhất mỗi ngày.Nhóm MySQL theo và trả về tối đa hàng sai

CREATE TABLE IF NOT EXISTS `posts_points` (
    `post_id` int(10) unsigned NOT NULL, 
    `comments` smallint(5) unsigned NOT NULL, 
    `likes` smallint(5) unsigned NOT NULL, 
    `favorites` smallint(5) unsigned NOT NULL, 
    PRIMARY KEY (`post_id`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8; 


CREATE TABLE IF NOT EXISTS `posts` (
    `profile_id` int(10) unsigned NOT NULL, 
    `post_id` int(10) unsigned NOT NULL, 
    `pubdate_utc` datetime NOT NULL, 
    PRIMARY KEY (`post_id`), 
    KEY `profile_id` (`profile_id`), 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; 

Tôi đã thử truy vấn bên dưới. Nó trả về số điểm chính xác nhưng các cột khác chỉ là các hàng ngẫu nhiên. Tôi đang làm gì sai?

SELECT p.post_id, p.profile_id 
    , MAX(t1.score) 
    , DATE_FORMAT(t1.pubdate_utc, '%d %b') post_date 
    , DATE(t1.pubdate_utc) mydate 
FROM 
(
    SELECT p.profile_id, p.post_id, p.pubdate_utc 
     , (pp.comments + pp.likes + pp.favorites) AS score 
    FROM posts p 
    INNER JOIN posts_points pp ON p.post_id = pp.post_id 
) t1 
INNER JOIN posts p ON t1.post_id = p.post_id 
    AND t1.pubdate_utc = p.pubdate_utc 
GROUP BY mydate 
ORDER BY mydate DESC 
LIMIT 18; 
+2

1 cho bao gồm định nghĩa bảng – ManseUK

+0

Bạn sẽ không làm điều gì sai trái.Hàm tổng hợp không ảnh hưởng đến giá trị của các cột khác. Chúng sẽ xuất hiện là "ngẫu nhiên". –

+0

Phân nhóm theo ngày phải tạo ra hành vi kỳ quặc đó. – Alfabravo

Trả lời

0
Column1 Column2 
C  d 
A  any thing 
D  y 
B  z 

Nếu bạn đặt hàng dữ liệu này bằng cách COLUMN1 sau đó nó trông như thế này ..... orderby chỉ ra lệnh cho cột đầu tiên ....

Column1 Column2 
A  any thing 
B  z    
C  d 
D  y 
0

là một chút khó khăn để hiểu bạn muốn làm gì.

Các từ (cột (bài đăng, nhận xét, yêu thích) và PK), tôi hiểu rằng bạn cập nhật các giá trị ngày càng tăng và không ghi lại từng phiếu bầu.

này chọn trả về dữ liệu từ cầu môn, điểm số, bằng cách đặt hàng điểm lớn hơn, hạn chế đến 18.

 SELECT P.post_id, 
       P.profile_id, 
       (PP.comments + PP.likes + PP.favorites) AS score, 
       DATE_FORMAT (P.pubdate_utc, '%d %b') AS post_data, 
       DATE (P.pubdate_utc) AS mydate 
      FROM posts P 
    INNER JOIN posts_points PP 
      ON (= P.post_id PP.post_id) 
     ORDER BY 3 DESC 
     LIMIT 18; 

Nếu bạn muốn chọn được nhiều phiếu nhất trong ngày, bạn phải ghi thích/favs khác nhau, cần dữ liệu trong bảng đó (posts_points).

+0

'posts_points' là một summary_table tôi đã thực hiện để gỡ lỗi và tăng tốc mọi thứ. Mỗi nhận xét, thích và yêu thích thực sự được ghi lại riêng biệt. Có vẻ như truy vấn của bạn sẽ tìm thấy các bài đăng có số điểm cao nhất. Tôi đang cố gắng tìm bài đăng có số điểm cao nhất mỗi ngày trong 18 ngày qua. Tôi không biết nếu nó làm cho sence. – user1070125

+0

Xin chào, cấu trúc của nó như thế nào? Trường hợp ghi nhận/yêu thích/lượt thích ghi lại? Nếu cần thiết, bạn có thể thay đổi bảng? – Cristian

0

Wow! Khôn lanh. Ví dụ, luôn có khả năng quan hệ cho max.

Giải pháp dưới đây tạo danh sách trung gian của max_scores trong ngày, sau đó nhận được tất cả các bài đăng có điểm số bằng với mức tối đa cho ngày của họ. Nó trả về các mối quan hệ, vì vậy bạn có thể nhận được hai hàng trong một ngày nhất định. Tôi cầu xin sự tha thứ của bạn rằng tôi không thể kiểm tra điều này, vì vậy hãy đưa ra phản hồi và tôi chắc chắn rằng chúng tôi có thể làm điều này để làm những gì bạn cần.

SELECT p.profile_id, p.post_id, p.pubdate_utc 
, DATE_FORMAT(p.pubdate_utc, '%d %b') AS post_date 
, DATE(p.pubdate_utc) AS mydate 
, (pp.comments + pp.likes + pp.favorites) AS score 
FROM posts p 
INNER JOIN posts_points pp ON p.post_id = pp.post_id 
INNER JOIN 
(
    SELECT p.pubdate_utc AS max_date, 
    (pp.comments + pp.likes + pp.favorites) AS max_score 
    FROM posts p2 
    INNER JOIN posts_points pp2 ON p2.post_id = pp2.post_id 
) m ON score = m.max_score 
AND mydate = m.max_date 
ORDER BY mydate DESC 
LIMIT 18; 
0

bạn có thể thấy truy vấn .Inner truy vấn này là trước hết lấy những hàng mà có cùng post_id trong cả hai bảng hơn sum (pp.comments pp.likes + + pp.favorites) như điểm .Outer Query được lấy tối đa ghi điểm và thực hiện nhóm vào ngày khôn ngoan ....

SELECT post_id, profile_id 
    , MAX(score) 
    , DATE_FORMAT(pubdate_utc, '%d %b') post_date 
    , DATE(pubdate_utc) as mydate 
FROM 
(
    SELECT p.profile_id, p.post_id, p.pubdate_utc 
     , (pp.comments + pp.likes + pp.favorites) AS score 
    FROM posts p 
    INNER JOIN posts_points pp ON p.post_id = pp.post_id 
) 
GROUP BY pubdate_utc 
ORDER BY pubdate_utc DESC 
2

Tôi gặp phải vấn đề này mọi lúc. Khi MySQL chạy một hàm tổng hợp, đối với bất kỳ cột không được tổng hợp nào, nó chỉ đơn giản kéo dữ liệu đầu tiên mà nó chạy qua cho nhóm đó, cho dù đó là từ hàng MAX hay không. Vì vậy, những gì bạn phải làm là đặt hàng các dữ liệu trong một truy vấn bên trong như vậy mà các max là lần đầu tiên trong nhóm của họ. Xem liệu điều này có phù hợp với bạn:

SELECT t.post_id, 
     t.profile_id, 
     t.score, 
     t.pubdate_utc 
FROM (SELECT p.profile_id, 
      p.post_id, 
      p.pubdate_utc, 
      (pp.comments + pp.likes + pp.favorites) score 
     FROM posts p 
     JOIN posts_points pp ON p.post_id = pp.post_id 
     WHERE p.pubdate_utc >= DATE_ADD(DATE(NOW()), INTERVAL -17 DAY) 
     ORDER BY score DESC 
    ) t 
GROUP BY DATE(t.pubdate_utc) DESC 
; 

Lưu ý rằng tôi không sử dụng hàm MAX ở đây. Sắp xếp theo điểm giảm dần và sau đó nhóm theo ngày trong truy vấn bên ngoài sẽ kéo lên số điểm cao nhất theo ngày. Cũng lưu ý rằng tôi đặt mệnh đề WHERE trong truy vấn bên trong. Các truy vấn bên trong như thế này (tho đôi khi cần thiết) không hiệu quả lắm, vì chúng không có chỉ mục cho truy vấn bên ngoài để tối ưu hóa, vì vậy hãy đảm bảo tập kết quả bên trong của bạn nhỏ như nó có thể. Cuối cùng, hãy chú ý GROUP BY DATE (t.pubdate_utc). Nếu tôi không giảm nó xuống chỉ là thông tin ngày, sẽ có nhiều hơn 18 kết quả, như thời gian cũng được tính sau đó.

Chỉnh sửa: Thay đổi để INTERVAL -17 DAY từ bỏ đến 18 kết quả thay vì 19.

Các vấn đề liên quan