2009-09-02 47 views
12

Tôi có 2 bảng, một bảng "tài liệu" và một bảng "nội dung". Chúng trông giống như thế này (đã được đơn giản hóa):Chỉ hiển thị ngày gần đây nhất từ ​​bảng MySQL đã tham gia

document table: 
docID 
docTitle 

content table: 
contentID 
docID 
dateAdded 
content 

Đối với mọi thay đổi nội dung, một bản ghi mới được chèn vào bảng "nội dung". Bằng cách này, có một lịch sử hoàn chỉnh của tất cả các thay đổi. Tôi muốn có danh sách tất cả các tài liệu, với nội dung mới nhất đã tham gia. Nó sẽ trả về docID, docTitle và bản ghi nội dung liên quan với giá trị "dateAdded" mới nhất. Não của tôi đang thất bại ngay bây giờ, tôi sẽ tạo ra sự tham gia này như thế nào?

+2

lẽ đổi tên câu hỏi này cho một cái gì đó mô tả giống như "Chỉ ngày gần đây nhất từ ​​bảng tham gia"? –

+0

@Gorgapor: Cuộc gọi tốt, tôi đã cập nhật tiêu đề. –

Trả lời

26

Điều này có thể được thực hiện với một subquery:

SELECT d.docID, docTitle, c.dateAdded, c.content 
FROM document d LEFT JOIN content c ON c.docID = d.docID 
WHERE dateAdded IS NULL 
    OR dateAdded = (
     SELECT MAX(dateAdded) 
     FROM content c2 
     WHERE c2.docID = d.docID 
    ) 

này được biết đến như một truy vấn "groupwise maximum"

Chỉnh sửa: Thực hiện các truy vấn trả lại toàn bộ hàng tài liệu, với NULLs nếu không có nội dung liên quan.

+2

Cảm ơn bạn đã đặt tên. Bất cứ khi nào tôi có một câu hỏi SQL, tôi không bao giờ biết những gì để Google, mà làm cho nó khó khăn hơn để tìm một giải pháp. :) –

+0

Truy vấn này có hoạt động khi không có bản ghi nội dung cho tài liệu không? Tôi vẫn muốn nó liệt kê tài liệu, và chỉ trả về null cho các trường dateAdded và content. –

+0

đã cập nhật truy vấn để trả lại tất cả các hàng tài liệu –

0

Bạn có thể không chỉ thực hiện một phép nối đơn giản và sắp xếp theo ngày được thêm vào, và chỉ lấy bản ghi đầu tiên?

SELECT docTable.docId, docTable.docTitle from docTable 
INNER JOIN content ON content.docID = docTable.contentID 
WHERE docTable.docId = <some id> 
ORDER BY content.dateAdded DESC 
+0

Tôi thnk bạn muốn đơn đặt hàng là DESC nên phiên bản mới nhất là trước tiên. Ngoài ra, nếu bạn thêm "LIMIT 1", bạn sẽ nhận được một hàng. – Craig

+0

Quyền của bạn về việc đặt hàng. Đối với giới hạn, bạn cũng phải, tôi chỉ còn lại mà ra bởi vì tôi đã không chắc chắn về công nghệ cơ sở dữ liệu. Lệnh đó có thể thay đổi (theo như tôi biết). – Zoidberg

-1

Đây là một giải pháp 2 truy vấn:

Đầu tiên truy vấn:

select docID, max(dateadded) from [TblContent] group by docID 

Thứ hai truy vấn:

select [TblDocument].* from [TblDocument] 
inner join [TblDocument] on [TblDocument].[Docid]=[FirstQuery].[DocID] 
+0

Điều này sẽ yêu cầu một truy vấn riêng biệt cho mỗi hàng, không chỉ hai truy vấn. –

-1

thử điều này:

select d.id, d.docTitle, MAX(c.dateAdd) 
from document_table d 
left join content_table c 
on d.id = c.docId 
group by d.id 

Đây là suy nghĩ đằng sau nó: bảng tài liệu giả sử có ghi A liên quan đến nội dung (1, 2, 3, 4) và B liên quan đến (5, 6, 7, 8)

document  content 

A    1 
      2 
        3 
      4 

B    5 
      6 
      7 
      8 

một bên tham gia với max (dateadded) sẽ cung cấp cho bạn

document  content  max(dateadded) 

A    1   1-1-2009... 

A    2   1-1-2009... 

A    3   1-1-2009... 

A    4   1-1-2009... 

B    5   2-1-2009... 

B    6   2-1-2009... 

B    7   2-1-2009... 

B    8   2-1-2009... 

sau khi nhóm của id tài liệu bạn sẽ nhận được

document content  max(dateadded) 

A   1   1-1-2009... 

B   5   2-1-2009... 

lưu ý: id nội dung không phù hợp cần thiết id của max dateadded

+0

Có thể trả lại các tài liệu chưa có hồ sơ nội dung liên quan hay không bằng cách thay đổi điều này thành một kết nối bên ngoài, hoặc sẽ thay đổi hành vi? Ngoài ra, điều này cũng có thể trả về các trường contentID và nội dung bằng cách bao gồm chúng trong phần lựa chọn, hay nó sẽ làm hỏng nó? –

+0

Đây có phải là Sql của tôi không? Bởi vì nếu nó không phải là, tùy thuộc vào cơ sở dữ liệu, bạn có thể không có khả năng chọn bất cứ thứ gì không có trong nhóm theo mệnh đề. – Zoidberg

+0

bạn có thể tham gia trái, nhưng bạn không thể đặt cột contentID ở đó. –

4

Sử dụng:

SELECT t.docid, 
     t.docTitle, 
     mc.dateAdded, 
     mc.content 
    FROM DOCUMENT t 
    JOIN (SELECT c.docid, 
       c.content, 
       MAX(c.dateAdded) 
      FROM CONTENT c 
     GROUP BY c.docid, c.content) mc ON mc.docid = t.docid 
            AND mc.dateadded = t.dateadded 

này cần được nhanh hơn so với một subquery tương quan.

Alternative cho khi không có hồ sơ nội dung cho một tài liệu:

SELECT t.docid, 
      t.docTitle, 
      mc.dateAdded, 
      mc.content 
    FROM DOCUMENT t 
LEFT JOIN (SELECT c.docid, 
        c.content, 
        MAX(c.dateAdded) 
      FROM CONTENT c 
     GROUP BY c.docid, c.content) mc ON mc.docid = t.docid 
            AND mc.dateadded = t.dateadded 
Các vấn đề liên quan