简体   繁体   中英

Puzzler: How To Group Rows By A Particular Sum of a Particular Column

How to burst the following rows into 3 groups where the sum of "dollars" is 10. All rows must be used and none more than once.

row|dollars
1|1
2|1
3|1
4|1
5|1
6|1
7|3
8|4
9|7
10|10

One (of many possible) desired outcomes would be...

Row Group 1 = 10
Row Group 2 = 7,9
Row Group 3 = 1,2,3,4,5,6,8

Extra Credit: When it's not mathematically possible to get a sum of exactly $10 in each group, is there a formula for getting us closest to that?

I though maybe " HAVING sum(dollar) = 10 " or, for a close solution, just sorting and distributing one row to one group, but that didn't get me close.

Group Row By Sum of Specific Column equal to Specific Value sort of touches on this, but, assuming their could be millions of rows, there would be performance issues. I'm stumped.

If it helps, I'm using php and mysql. A sql-only solution would be ideal, but some combination would be great too. Thanks for any suggestions.

Edit: If I wasn't clear, I want to return the rows that make this possible, not just "group by" them.

I don't think you could do it with just sql, but it could certainly help out. I'd start by having a query like select * from data where dollars <= 10 order by dollars desc and then make an algorithm in php that went through the results and added up dollars until it found three sets that add up to 10.

It would start out adding from larger to smaller until it found a correct sum, then store it, remove those items from the list and start again, three times. I'm on my phone, but will update the answer with a working example when I get to my computer.

EDIT: got to my computer. This is very messy code, but it should lead you in the right direction.

$dataset = [10,7,4,3,1,1,1,1,1,1];
$results = [];

function add_to_ten(&$data) {
    $sum = 0;
    $results = [];

    foreach ($data as $index => &$datum) {
        if ($datum == 0) {
            continue;
        }
        if ($sum + $datum <= 10) {
            $sum += $datum;
            $results[] = $index;
            $datum = 0;
        }
        if ($sum == 10) {
            return $results;
        }
    }
}

print_r(add_to_ten($dataset));
print_r(add_to_ten($dataset));
print_r(add_to_ten($dataset));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM