Mysql
 sql >> Database >  >> RDS >> Mysql

Trova le combinazioni che soddisfano un criterio a intervalli

Devi limitare il costo massimo totale, o il numero di combinazioni salirà al cielo, non importa come cerchi di trovarle. Nell'esempio seguente è limitato a 75, ma puoi provare altri valori per vederlo, puoi comunque trovare risultati in un tempo ragionevole.

Puoi anche adattare questa soluzione per aggiornare la tabella delle combinazioni sugli inserti o gli aggiornamenti per la tua tabella principale, permettendoti di ottenere risultati estremamente rapidi per qualsiasi intervallo che non superi il limite impostato (ma ovviamente rallentando gli inserti poiché è lì che viene svolto tutto il lavoro).

Crea tabelle e attiva:

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 ;

Quindi compila utilizzando:

INSERT INTO newparts( name, price )
SELECT part_number, cost FROM yourtable
WHERE cost <= 75;

o (come dati di prova)

INSERT INTO newparts( name, price ) VALUES
('A012', 5),('A034', 1),('A084', 10),('A094', 25),('A233', 75),
('A343', 75),('A370', 50),('B309', 13),('C124', 78);

E finalmente ottieni il tuo risultato usando:

SELECT * FROM total_max75 WHERE total BETWEEN 70 AND 75;

Puoi inserire qualsiasi intervallo qui con un massimo inferiore a 75 (o qualsiasi cosa tu abbia impostato come limite nella parte di creazione della tabella e nell'attivazione).

Risultati:

A084, A370, B309        73 (you missed this one in your question)
A034, A084, A370, B309  74
A233                    75
A343                    75
A094, A370              75