MySQL值附近,join,abs和动态值

时间:2018-01-25 14:49:15

标签: mysql sql

目标是获取最接近的m3和重量数的价格并将其放在表格中。

此示例适用于我。但我硬编码m3weightcountrytransportername

查询1:

SELECT
  country,
  transportername,
  ABS(m3-0.5) as ABS_M3 ,
  m3,
  ABS(weight-5) as ABS_weight,
  weight,
  price
FROM database.transportcost
WHERE   m3      >= 0.5    AND
        weight  >= 5      AND
        country = "GB"    AND
        transportername like '%aa%'
Group by transportername
Order by ABS(m3-0.5) +
         ABS(weight-5) +
         price

现在我想从其他表中获取硬代码值。我不知道我需要在~~xx.volumen~~~~xx.gewicht~~中放置什么价值。

QUERY2:

INSERT INTO database.transportcostPerItem (sku,country,transportname,weight,m3,price)
SELECT g.orderitemid, p2.country, p2.transportername, p2.weight, p2.m3, p2.price
FROM database.orderitem g
JOIN database.order i                 on i.orderid     = g.orderid
JOIN database.matrixtable xx       on g.orderitemid = xx.sku
JOIN database.vlog cc                on i.orderid     = cc.orderid
JOIN
(
  SELECT   *
  FROM database.transportcost
  Group by transportername
  Order by ABS(m3-~~xx.volumen~~) +
           ABS(weight-~~xx.gewicht~~) +
           price
) as p2 on p2.country          = i._country            AND
           p2.transportername  = cc._transportername   AND
           p2.weight           = xx.gewicht            AND
           p2.m3               = xx.volumen

;

编辑:

示例数据

Table: database.transportcost

country | transportername | m3     | weight | price
--------+-----------------+--------+--------+--------
GB      | aa              |  50.00 |    50  |  77.70
GB      | bb              |   0.50 |   125  |  83.19
GB      | cc              |   0.50 |   125  |  96.03
GB      | bb              |   0.60 |   150  |  83.19
GB      | aa              |  75.00 |    75  |  89.04
GB      | cc              |   0.60 |   150  |  96.03
GB      | dd              |  50.00 |    50  | 163.38
GB      | cc              |   0.70 |   175  |  96.03
GB      | bb              |   0.70 |   175  |  96.85
GB      | ee              |   0.53 |   175  | 102.78
GB      | gg              |   0.53 |   175  | 110.37
GB      | aa              | 100.00 |   100  |  89.04
GB      | cc              |   0.80 |   200  |  96.03
GB      | bb              |   0.80 |   200  |  96.85
GB      | ff              |   0.60 |   200  | 110.33
DE      | aaa             |   0.50 |    50  |  26.40
DE      | bbb             |   0.50 |    75  |  31.84
DE      | aaa             |   0.75 |    75  |  34.19
DE      | ccc             |   0.50 |   100  |  34.17
DE      | bbb             |   0.67 |   100  |  35.47
DE      | ccc             |   1.00 |   100  |  37.59
DE      | ddd             |   0.50 |   100  |  62.38
DE      | ccc             |   0.63 |   125  |  43.04
DE      | bbb             |   0.83 |   125  |  44.24
DE      | aaa             |   0.93 |   125  |  45.84
DE      | eee             |   0.50 |   125  |  53.80
DE      | fff             |   0.50 |   125  |  54.02
国家Query 1

GB结果

country | transportername | ABS_M3                | m3    | ABS_weight | weight | price
--------+-----------------+-----------------------+-------+------------+--------+-------
GB      | aa              | 49.5                  | 50.00 | 45         |  50    |  77.70
GB      | bb              |  0                    |  0.50 | 120        | 125    |  83.19
GB      | cc              |  0                    |  0.50 | 120        | 125    |  96.03
GB      | dd              | 49.5                  | 50.00 | 45         |  50    | 163.38
GB      | ee              |  0.030000000000000027 |  0.53 | 170        | 175    | 102.78
GB      | gg              |  0.030000000000000027 |  0.53 | 170        | 175    | 110.37
国家Query 1

DE结果

country | transportername | ABS_M3 | m3   | ABS_weight | weight | price
--------+-----------------+--------+------+------------+--------+-------
DE      | aaa             | 0      | 0.50 |  45        |   50   |  26.40
DE      | bbb             | 0      | 0.50 |  70        |   75   |  31.84
DE      | ccc             | 0      | 0.50 |  95        |  100   |  34.17
DE      | ddd             | 0      | 0.50 |  95        |  100   |  62.38
DE      | eee             | 0      | 0.50 | 120        |  125   |  53.80
DE      | fff             | 0      | 0.50 | 120        |  125   |  54.02
DE      | ggg             | 0      | 0.50 | 195        |  200   |  87.29

最终Query 2的结果应如下所示:

Table: database.transportcostPerItem

orderitemid | country | transportername | m3  | weight | price
------------+---------+-----------------+-----+--------+------
1           | GB      | aa              | 0,5 | 5      | 77.70
2           | DE      | aaa             | 0,5 | 5      | 26.40

2 个答案:

答案 0 :(得分:1)

看来你只是在寻找最便宜的运输给定的m3和重量。在第一步中,您将找到至少m3和重量的所有运输。其中你选择最低的价格。

select *
from transportcost
where country = 'GB'
  and m3 >= 0.5
  and weight >= 5
order by price
limit 1;

如果你想要最接近你给定的m3和重量的测量,即使那个传输更贵,你可以按百分比的总和来订购:

select *
from transportcost
where country = 'GB'
  and m3 >= 0.5
  and weight >= 5
order by m3 / 0.5 + weight / 5, price
limit 1;

现在,不是给定m3,权重,国家/地区和运输商名称,而是从订单明细表中获取值。如果这只是一个订单详细记录,那么方法将完全相同,而不是与固定值(m3 >= 0.5)进行比较,而是与订单明细记录的值(transportcost.m3 >= orderdetail.m3)进行比较。唉,有多个订单详细信息记录,这种方法不再起作用,因为我们不能将结果限制为一行,而是每个订单详细记录需要一行。这可以通过标准SQL中的窗口函数(ROW_NUMBERRANK等)或横向连接(CROSS APPLY)来解决。 MySQL既没有。

以下是加入运输成本表的方法:

select *
from <your order tables>
join transportcost tc
where tc.country = i._country 
  and tc._transportername = cc._transportername 
  and tc.m3 >= xx.volumen
  and tc.weight >= xx.gewicht;

现在,您必须找到一种方法对结果进行排名,以便只为每个订单详细信息获得最佳匹配。一种方法是使用变量模拟ROW_NUMBER。您可能希望在其他答案中查找此内容。另一个是SELECT clause中的限制子查询,但为此,您需要一个列来标识传输成本表中的记录。假设您添加了一个名为ID的列,并使用唯一值填充...

select <some order columns>, tc.*
from
(
  select <some order columns>,
    (
      select id
      from transportcost tc
      where tc.country = i._country 
        and tc._transportername = cc._transportername 
        and tc.m3 >= xx.volumen
        and tc.weight >= xx.gewicht
      order by tc.m3 / xx.volumen + tc.weight / xx.gewicht, tc.price
      limit 1
    ) as best_transportcost_id
  from <your order tables>
) data
join transportcost tc
where tc.id = data.best_transportcost_id;

(您可以通过连接值以某种方式在没有ID的情况下执行此操作,例如'GB-aa-50.00-50-77.70',以便有一个标识运输成本记录的字符串,但我不建议这样做。最好有一个带有快速查找索引的唯一ID。更好的方法是使用更好的DBMS: - )

答案 1 :(得分:0)

我使用了@Thorsten的解决方案。

这是结果

    INSERT INTO database.transportcostperitem (transportcostID, orderID, sku, country, transportername, weight, m3,price,shippingmethod,shippingstatus,shippingDate)
SELECT  
        transportcostID, 
        orderID,
        sku, 
        _country,
        transportername,
        transportTmp._weightReal,
        transportTmp._m3  ,
        price, 
        _shippingMethod,
        _shippingStatus,
        _shippingDate
FROM(

    SELECT 
        b.orderID,
        o.sku,      
        b.transporter,      
        o._country, 
        i._shippingMethod,
        i._shippingStatus,
        i._shippingDate,
        o._m3,
        o._weightReal,
        ( 

                SELECT  id
                FROM database.transportcost tc
                where
                    tc.transportername      = b._transporterName    AND
                    tc.country              = o._country            AND
                    tc.weight               >= o._weightReal        AND 
                    tc.m3                   >= o._m3
                order by    o._m3 / tc.m3  +  o._weightReal / tc.weight , tc.price
                limit 1

        ) as transportcostID
    FROM database.orderitem             o
    JOIN database.order                 i       on i.orderID = o.orderID 
    JOIN database.vlog                  b       on b.orderID = o.orderID    
    WHERE sku >0 

)as transportTmp
JOIN database.transportcost tc
where   tc.id = transportcostID     AND
        _shippingMethod is not null
orderID by sku
;