与其在 PHP 中硬编码任何内容,运费/运费应该在其他人提到的数据库表中。一个匆忙起草的示例数据库模式和查询应该显示如何完成和使用 - 尽管毫无疑问可以进行大量改进。
给定一个粗略的架构如下:
create table `seller-products` (
`id` int(10) unsigned not null auto_increment,
`seller` varchar(50) not null,
`product` varchar(50) not null,
`weight` int(11) not null default '0',
primary key (`id`)
)
engine=innodb
auto_increment=5;
create table `buyer-products` (
`id` int(10) unsigned not null auto_increment,
`buyer` varchar(50) not null,
`seller` int(10) unsigned not null,
`qty` int(10) unsigned not null,
primary key (`id`),
index `seller` (`seller`)
)
engine=innodb
auto_increment=3;
create table `seller-freight` (
`id` int(10) unsigned not null auto_increment,
`low` int(10) unsigned not null,
`high` int(10) unsigned not null,
`charge` decimal(8,2) unsigned not null,
primary key (`id`)
)
engine=innodb
auto_increment=13;
用一些虚拟数据来模拟一些问题数据:
insert into `seller-products` (`id`, `seller`, `product`, `weight`) values
(1, 'jacob', 'mobile', 500),
(2, 'john', 'laptop', 3500),
(3, 'kiki', 'charger', 1000),
(4, 'dani', 'keyboard', 1500);
insert into `buyer-products` (`id`, `buyer`, `seller`, `qty`) values
(1, 'susan', 1, 3),
(2, 'charlie', 2, 5),
(3, 'lisa', 3, 3);
如果权重介于低值和高值之间,则使用一种矩阵查找表来设置价格。
insert into `seller-freight` (`id`, `low`, `high`, `charge`) values
(1, 0, 500, 10.00),
(2, 501, 1000, 15.00),
(3, 1001, 2000, 25.00),
(4, 2001, 3000, 35.00),
(5, 3001, 4000, 45.00),
(6, 4001, 5000, 55.00),
(7, 5001, 6000, 62.50),
(8, 6001, 7000, 70.00),
(9, 7001, 8000, 77.50),
(10, 8001, 9000, 95.00),
(11, 9001, 10000, 100.00),
(12, 10001, 1000000000, 0.00);
mysql> select * from `seller-products`;
+----+--------+----------+--------+
| id | seller | product | weight |
+----+--------+----------+--------+
| 1 | Jacob | Mobile | 500 |
| 2 | John | Laptop | 3500 |
| 3 | Kiki | Charger | 1000 |
| 4 | Dani | Keyboard | 1500 |
+----+--------+----------+--------+
mysql> select * from `buyer-products`;
+----+---------+--------+-----+
| id | buyer | seller | qty |
+----+---------+--------+-----+
| 1 | Susan | 1 | 3 |
| 2 | Charlie | 2 | 5 |
| 3 | Lisa | 3 | 3 |
+----+---------+--------+-----+
mysql> select * from `seller-freight`;
+----+-------+------------+-----------+
| id | low | high | charge |
+----+-------+------------+-----------+
| 1 | 0 | 500 | 10.00 |
| 2 | 501 | 1000 | 15.00 |
| 3 | 1001 | 2000 | 25.00 |
| 4 | 2001 | 3000 | 35.00 |
| 5 | 3001 | 4000 | 45.00 |
| 6 | 4001 | 5000 | 55.00 |
| 7 | 5001 | 6000 | 62.50 |
| 8 | 6001 | 7000 | 70.00 |
| 9 | 7001 | 8000 | 77.50 |
| 10 | 8001 | 9000 | 95.00 |
| 11 | 9001 | 10000 | 100.00 |
| 12 | 10001 | 1000000000 | 0.00 |
+----+-------+------------+-----------+
从所有表中提取以计算每位客户的运费的快速查询:
select
sp.`product`,
sp.`seller`,
bp.`buyer`,
bp.`qty`,
sp.`weight` as `item-weight`,
( sp.weight * bp.qty ) as `gross-weight`,
case
when ( sp.weight * bp.qty ) > 10000 then 'Error: Over limit'
else
( select `charge` from `seller-freight` where sp.weight * bp.qty between `low` and `high` )
end as `charge`
from `buyer-products` bp
join `seller-products` sp on sp.id=bp.`seller`;
+---------+--------+---------+-----+-------------+--------------+-------------------+
| product | seller | buyer | qty | item-weight | gross-weight | charge |
+---------+--------+---------+-----+-------------+--------------+-------------------+
| Mobile | Jacob | Susan | 3 | 500 | 1500 | 25.00 |
| Laptop | John | Charlie | 5 | 3500 | 17500 | Error: Over limit |
| Charger | Kiki | Lisa | 3 | 1000 | 3000 | 35.00 |
+---------+--------+---------+-----+-------------+--------------+-------------------+
要完成grand-total 类型的图,一种方法可能是使用一个运行时变量,该变量会以某个值递增。在这种情况下,您希望显示客户产生的总费用,因此您可能会执行以下操作:
set @buyer='susan';
set @gt=0;
select
sp.`product`,
sp.`seller`,
bp.`buyer`,
bp.`qty`,
sp.`weight` as `item-weight`,
( sp.weight * bp.qty ) as `gross-weight`,
case
when ( sp.weight * bp.qty ) > 10000 then 'Error: Over limit'
else
( select `charge` from `seller-freight` where sp.weight * bp.qty between `low` and `high` )
end as `charge`,
@gt:=@gt + (
case
when ( sp.weight * bp.qty ) > 10000 then 0
else
( select `charge` from `seller-freight` where sp.weight * bp.qty between `low` and `high` )
end
) as `total-charges`
from `buyer-products` bp
join `seller-products` sp on sp.id=bp.`seller`
where bp.`buyer`=@buyer;
而且,在添加了几行虚拟数据后,上述查询会产生如下结果:
+----------+--------+-------+-----+-------------+--------------+--------+---------------+
| product | seller | buyer | qty | item-weight | gross-weight | charge | total-charges |
+----------+--------+-------+-----+-------------+--------------+--------+---------------+
| Mobile | Jacob | Susan | 3 | 500 | 1500 | 25.00 | 25.00 |
| Laptop | John | Susan | 1 | 3500 | 3500 | 45.00 | 70.00 |
| Charger | Kiki | Susan | 1 | 1000 | 1000 | 15.00 | 85.00 |
| Keyboard | Dani | Susan | 2 | 1500 | 3000 | 35.00 | 120.00 |
+----------+--------+-------+-----+-------------+--------------+--------+---------------+
显然,苏珊用 3 部手机做得不好