2013-06-14 35 views
5

Vì vậy, tôi loại bối rối ở đây, tôi có một thiết lập bảng như thế nàyHạn chế SQL bằng tổng giá trị của hàng

+-----------+------+ 
| Timestamp | Size | 
+-----------+------+ 
| 1-1-13 + 10.3 + 
+-----------+------+ 
| 1-3-13 + 6.7 + 
+-----------+------+ 
| 1-5-13 + 3.0 + 
+-----------+------+ 
| 1-9-13 + 11.4 + 
+-----------+------+ 

Và tôi tự hỏi nếu có cách nào để chạy một truy vấn như thế này

SELECT * FROM table ORDER BY timestamp ASC LIMIT BY (SUM(size) <= 20.0);

này nên lấy ba hàng đầu tiên, bởi vì tổng các kích thước trong 3 hàng đầu tiên là 20. Tuy nhiên, nó có thể không phải lúc nào 3 hàng đó bằng 20. Đôi khi dòng đầu tiên có thể có giá trị là 20 và trong trường hợp đó, nó chỉ lấy giá trị đầu tiên.

Tôi đã biết rằng điều này có thể nhanh chóng tính tổng trong PHP sau khi truy vấn được chạy, nhưng tôi đang cố gắng thực hiện điều này chỉ với MySQL.

+0

Vì vậy, bạn muốn có một tổng chạy? –

+0

Trong ANSI SQL, bạn chọn các hàng của một số bảng (quan hệ) dựa trên các tiêu chí được so khớp cho MỌI ROW SINGLE của đầu ra. Trong ví dụ của bạn, tiêu chí thay đổi với mọi hàng mới. Không chắc chắn, nhưng tôi nghĩ rằng nó sẽ yêu cầu chức năng PL/SQL. Lưu ý cách ORDER hoạt động - tùy thuộc vào việc sử dụng truy vấn phụ, bạn sẽ nhận được các kết quả khác nhau, tùy thuộc vào việc bạn muốn sắp xếp đầu ra hay nhập dữ liệu nào phù hợp với điều kiện của bạn và ORDER không được sử dụng như vậy. LIMIT (hoặc OFFSET) có thể được sử dụng cho số lượng giới hạn đơn giản của các hàng trên đầu ra, không phải bởi biểu thức. –

Trả lời

3

Bạn muốn thêm một tổng chạy, và hạn chế trên cơ sở đó, sau đây nên làm việc:

SET @runtot:=0; 
SELECT 
    q1.t, 
    q1.s, 
    (@runtot := @runtot + q1.s) AS rt 
FROM 
    (SELECT Date AS t, 
    SIZE AS s 
    FROM Table1 
    ORDER BY Date 
    ) AS q1 
WHERE @runtot + q1.s <= 20 

Edit: Demo ở đây - SQL Fiddle

+0

Hóa ra sau một chút nghiên cứu, bạn thực sự chính xác. Tính toán tổng số hoạt động tốt hơn so với tham gia. Cảm ơn câu trả lời! – garetmckinley

4
SELECT * FROM ints ORDER BY i; 
+---+ 
| i | 
+---+ 
| 0 | 
| 1 | 
| 2 | 
| 3 | 
| 4 | 
| 5 | 
| 6 | 
| 7 | 
| 8 | 
| 9 | 
+---+ 

SELECT x.* ,SUM(y.i) FROM ints x JOIN ints y ON y.i <= x.i GROUP BY x.i; 
+---+----------+ 
| i | SUM(y.i) | 
+---+----------+ 
| 0 |  0 | 
| 1 |  1 | 
| 2 |  3 | 
| 3 |  6 | 
| 4 |  10 | 
| 5 |  15 | 
| 6 |  21 | 
| 7 |  28 | 
| 8 |  36 | 
| 9 |  45 | 
+---+----------+ 

SELECT x.* ,SUM(y.i) FROM ints x JOIN ints y ON y.i <= x.i GROUP BY x.i HAVING SUM(y.i) <= 20; 
+---+----------+ 
| i | SUM(y.i) | 
+---+----------+ 
| 0 |  0 | 
| 1 |  1 | 
| 2 |  3 | 
| 3 |  6 | 
| 4 |  10 | 
| 5 |  15 | 
+---+----------+ 
+0

Tôi đã cố gắng giải quyết vấn đề bằng truy vấn con, tham gia tốt hơn và dễ đọc hơn. +1 – Marcassin

+0

Wow, câu trả lời tuyệt vời. Có bất kỳ vấn đề hiệu suất nào làm việc này không? – garetmckinley

+0

chạy tổng bằng biến giúp tiết kiệm chi phí của một tự JOIN. –

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