2008-11-13 4 views
6

Tôi đang tìm cách chọn cho đến khi đạt đến tổng.SQL: Chọn "cho đến"

Bảng "tài liệu" của tôi có các trường "tag_id" và "size".

Tôi muốn chọn tất cả tài liệu có tag_id = 26 nhưng tôi biết tôi chỉ có thể xử lý 600 đơn vị kích thước. Vì vậy, không có vấn đề gì khi chọn 100 tài liệu và loại bỏ 90 tài liệu khi tôi có thể biết rằng 10 tài liệu đầu tiên đã được thêm tối đa> 600 đơn vị.

Vì vậy, mục tiêu là: không mang lại nhiều dữ liệu để phân tích khi tôi sắp loại bỏ hầu hết dữ liệu.

... nhưng tôi cũng thực sự muốn tránh giới thiệu làm việc với con trỏ cho ứng dụng này.

Tôi đang sử dụng mysql.

+0

MySQL có chức năng phân tích không? –

+0

Vì sẽ có nhiều kết hợp các tài liệu thêm vào> 600, làm cách nào bạn biết bạn muốn sử dụng tài liệu nào? Hoặc nó không quan trọng? – Kev

+0

Sở thích được cung cấp cho các tài liệu được thêm gần đây (có trường date_created mà chúng tôi sẽ đặt hàng) – jhalb

Trả lời

7

Bạn cần một số cách để đặt hàng hồ sơ nào được ưu tiên hơn những người khác khi thêm tối đa đơn vị tối đa của bạn. Nếu không, làm thế nào để bạn biết được tập hợp các bản ghi nào tổng cộng lên đến 600 để bạn giữ?

SELECT d.id, d.size, d.date_created 
FROM documents d 
INNER JOIN documents d2 ON d2.tag_id=d.tag_id AND d2.date_created >= d.date_created 
WHERE d.tag_id=26 
GROUP BY d.id, d.size, d.date_created 
HAVING sum(d2.size) <= 600 
ORDER BY d.date_created DESC 

Đây chỉ là một truy vấn cơ bản để giúp bạn bắt đầu, và có một số vấn đề vẫn còn để giải quyết:

  • Nó dừng lại ở < = 600, vì vậy trong nhiều trường hợp bạn sẽ không điền chính xác giới hạn kích thước của bạn. Điều này có nghĩa là bạn có thể muốn tinh chỉnh nó để cho phép một bản ghi nữa. Ví dụ, nếu bản ghi đầu tiên là> 600 truy vấn sẽ không trả lại gì cả, và đó có thể là một vấn đề.
  • Nó sẽ không làm bất cứ điều gì để kiểm tra các bản ghi nhỏ hơn sau đó mà vẫn có thể vừa với giới hạn.
  • Các bản ghi có giá trị date_created giống hệt nhau có thể là loại 'được tính hai lần' tại đây và ở đó.

chỉnh sửa
Cập nhật từ ông cho biết thêm thông tin rằng ông sắp xếp theo ngày.

+0

Tôi đã bắt đầu đăng một cái gì đó rất giống nhau, mặc dù sử dụng một cái nhìn phụ trợ. Của bạn tốt hơn. –

+0

Đó là thông minh hơn so với câu trả lời của tôi quá. :) – Kev

0

Đây là ít hiệu quả, nhưng nó tránh một con trỏ (giả sử bảng tài liệu của bạn cũng có một cột id nối tiếp):

select a.id, (select sum(b.size) from documents b where b.id <= a.id and b.tag_id = 26) 
from documents a 
where a.tag_id = 26 
order by a.id 

Ngoài ra, điều này đã được thực hiện trong pgsql, vì vậy tôi không chắc chắn nếu cú ​​pháp chính xác này sẽ hoạt động trong mysql.

Sau đó, bạn có thể bọc điều này trong truy vấn khác tìm kiếm những người có tổng> 600 (bạn sẽ phải đặt tên cột tổng) và lấy id đầu tiên. Sau đó, xử lý tất cả các id bên dưới và bao gồm cả id đó.

+0

Er, nếu không có id, sau đó sử dụng dấu thời gian được tạo. – Kev

0

Trước tiên, bạn phải lưu trữ tài liệu trong biến bảng, sắp xếp chúng theo thứ tự bạn muốn truy xuất, sau đó cập nhật từng hàng có giá trị cộng dồn để bạn có thể chọn trên đó.

declare @documents_temp table (
    tag_id int, 
    size int, 
    cumulative_size int null) 

insert into @documents_temp 
select tag_id, size, size from documents order by tag_id 

update @documents_temp d set d.cumulative_size = d.size + 
    (select top 1 cumulative_size from @documents_temp 
    where tag_id < d.tag_id order by tag_id desc) 

select tag_id, size from @documents_temp where cumulative_size <= 600 

Không biết liệu nó có đáng không.