Vous devez limiter au maximum le coût total, sinon le nombre de combinaisons montera vers le ciel, peu importe comment vous essayez de les trouver. Dans l'exemple suivant, il est limité à 75, mais vous pouvez essayer d'autres valeurs pour voir que vous pouvez toujours trouver des résultats dans un délai raisonnable.
Vous pouvez également adapter cette solution pour mettre à jour la table des combinaisons sur les insertions ou les mises à jour de votre table principale, vous permettant d'obtenir des résultats extrêmement rapides pour toute plage qui ne dépasse pas la limite définie (mais en ralentissant évidemment les insertions car c'est là que tout le travail est fait).
Créer des tables et déclencher :
CREATE TABLE `total_max75` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`parts` varchar(255) NOT NULL,
`num` int(11) NOT NULL,
`total` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `total` (`total`,`num`)
);
CREATE TABLE `newparts` (
`name` char(4) NOT NULL,
`price` int(11) NOT NULL,
PRIMARY KEY (`name`)
);
DELIMITER //
CREATE TRIGGER addtotal AFTER INSERT ON newparts
FOR EACH ROW
BEGIN
IF NEW.price <= 75 THEN
INSERT INTO total_max75 ( parts, num, total )
SELECT CONCAT( t.parts, ', ', NEW.name),
t.num+1, t.total+NEW.price
FROM total_max75 t
WHERE t.total <= 75 - NEW.price AND num < 40;
INSERT INTO total_max75( parts, num, total )
VALUES( NEW.name, 1, NEW.price );
END IF;
END//
DELIMITER ;
Remplissez ensuite en utilisant :
INSERT INTO newparts( name, price )
SELECT part_number, cost FROM yourtable
WHERE cost <= 75;
ou (comme données de test)
INSERT INTO newparts( name, price ) VALUES
('A012', 5),('A034', 1),('A084', 10),('A094', 25),('A233', 75),
('A343', 75),('A370', 50),('B309', 13),('C124', 78);
Et enfin obtenez votre résultat en utilisant :
SELECT * FROM total_max75 WHERE total BETWEEN 70 AND 75;
Vous pouvez mettre n'importe quelle plage ici avec un maximum inférieur à 75 (ou tout ce que vous avez défini comme limite dans la partie de création de table et le déclencheur).
Résultats :
A084, A370, B309 73 (you missed this one in your question)
A034, A084, A370, B309 74
A233 75
A343 75
A094, A370 75