Home > Net >  MYSQL Matching Samples by weight
MYSQL Matching Samples by weight

Time:06-26

I would like to reduce the number of samples by matching them for a specific product.

Conditions : The total weight does not exceed 200 pounds AND Reduce lightest and heavier samples wherever it’s possible

CREATE TABLE 'sample' ('product' TEXT,'id_sample' INTEGER,'weight_sample' INTEGER);
INSERT INTO 'sample' ('product','id_sample','weight_sample') VALUES 
 ('A','1001','160'), 
 ('A','1002','40'), 
 ('A','1003','5'), 
 ('B','1004','195'), 
 ('B','1005','190'), 
 ('B','1006','180'), 
 ('B','1007','160'), 
 ('B','1008','26'), 
 ('B','1009','12');
    

Table

product id_sample weight_sample
A 1001 160
A 1002 40
A 1003 5
B 1004 195
B 1005 190
B 1006 180
B 1007 160
B 1008 26
B 1009 12

Output :

product id_sample1 weight_sample1 id_sample2 weight_sample2 total_weight
A 1001 160 1003 5 165
B 1006 180 1009 12 192
B 1007 160 1008 26 186

[OUTPUT IMG][1]

Greetings

EDIT :

WITH 
     M (product, N_ref, MIN_weight) as (
        SELECT product, count(id_sample), min(weight_sample) FROM sample GROUP BY product)
    ,X as (SELECT sample.*, M."MIN_weight", row_number() over(partition by sample.product order by weight_sample DESC, id_sample) as RN 
           FROM sample, M WHERE sample.product = M.product and M."MIN_weight" sample.weight_sample <= 200)
    ,Z (product, id_sample, weight_sample, RN, Id2_compl, MIN_weight) as (
        SELECT X.product, X.id_sample, X.weight_sample, X.RN, (M.N_ref-X.RN 1), M."MIN_weight"
        FROM X, M
        WHERE X.product = M.product)
    ,T (id_sample2, id_2, weight_sample2, product) as (
        SELECT Z2.id_sample, Z2.id2_compl, Z2.weight_sample, Z2.product
        FROM Z, Z Z2 
        WHERE Z2.RN = Z.id2_compl and Z.product = Z2.product)
SELECT 
    Z.product, Z.id_sample as "id_sample1", Z.weight_sample as "weight_sample1",
    T.id_sample2, T.weight_sample2, (Z.weight_sample T.weight_sample2) as "weight_total"
FROM Z, T
WHERE Z.product = T.product and Z.RN = T.id_2 and "id_sample1" <> "id_sample2" 
order by Z.product, weight_total

Here my code so far, but feel way too complicate and not working (!) [1]: https://i.stack.imgur.com/9jZ8r.png

CodePudding user response:

You could do something like this:

select
    a.product, a.id, a.weight, b.product, b.id, b.weight, a.weight   b.weight as total
from
    sample a inner join sample b on a.product = b.product and a.id < b.id
where
    a.weight   b.weight <= 200 and not exists(
        select 1 from sample x
        where x.product = a.product and x.id <> a.id and x.id <> b.id and
        (x.weight   a.weight <= 200 and x.weight   a.weight > a.weight   b.weight or
         x.weight   b.weight <= 200 and x.weight   b.weight > a.weight   b.weight)
    )

Gives the correct result except it wants to combine A 1001 with A 1002 to get a total of 200.

First we join on product and a.id < b.id because we don't want (a, a) or having both (a, b) and (b, a), one is enough.

Then the total weight conditions are applied and then we check with the not exists if a sample exists which can be combined with the ones selected to give a higher weight still <= 200. So each sample is only used once (or never) in the output.

  • Related