mysql表中查找和小於某個數的所有最前面的記錄?

例表如下,要查找記錄中Name為A,且Value的和小於X的所有最前面的記錄。

Id Name Value

1 A 20

2 A 25

3 B 12

4 A 18

5 B 17

6 A 33

比如,X=50,那就應該找出記錄1和2;X=65,那就應該找出記錄1、2、4。

有沒有快速的方法呢?還是只能遍歷?因為數據很多,幾十萬條...

謝謝!~


一句sql解決方式

SELECT `b`.`id`,(SELECT SUM(`value`) AS `sum`
FROM `table` AS `a`
WHERE `b`.`id` &>= `a`.`id` AND `name` = "A" ) AS `sum`
FROM `table` AS `b`
WHERE `name` = "A"
HAVING `sum` &< 50;

不過這樣的話要全表掃描兩遍,表大的話並不推薦這麼做。還是自己一行行遍歷更有效率些。


SELeCT * FROM t
WHERE id &<= ( SELECT MAX(id) FROM ( SELECT m2.id, SUM(m1.value) sv FROM t m1 INNER JOIN t m2 ON m1.id &<=m2.id AND m1.name = "A" WHERE m2.name = "A" AND m1.name = "A" GROUP BY m2.id HAVING sv &< 70 ) v ) AND name = "A"


set @x = 0;
select id, @x := @x + value as sum from table group by id having sum &< 50; set @x = null;

全表掃描是免不了的,不過在我機器上500000行的表也只用了0.8秒(第二次0.39秒),不知道是不是可以接受的時間。

----------------------------------

又想到一個增量的方法,每次拿100條,並且保存中間的值

set @sum = ?; -- 程序傳入
select id, @sum := @sum + values as sum from (
select * from table limit 100 offset ? -- offset由程序傳入,每次加100
) partial group by id having sum &< 50; select @sum; -- 將目前為止的sum記下,下次傳入。


關於優化層面,因為Name這一列似乎值不多,所以可以在這一列上建一個哈希索引,然後按照一樓提的的SQL語句寫就行了!


推薦閱讀:

以 MySQL 為例,如何進行 SQL 注入和防止被注入?
分享下你寫過的你覺得最厲害的sql語句?
請教一下大家,關於 MySQL 百萬數據量的 count(*) 查詢如何優化?
sql 查詢如何將結果集 輸出為一段字元串?
沒有任何基礎的人怎麼學SQL?

TAG:資料庫 | PHP | SQL | MySQL |