产品表:
shrimp
lobster
beef
special1
special2
我还有一个事务表,每行包含上表中的产品。我想计算交易表,所以我看到虾,龙虾和牛肉的数量。但是,具有special1的交易行应计为1x虾和1x龙虾,而special2应计为1x虾,1x龙虾和1x牛肉。
什么是可以帮助我完成此任务的最佳SQL语句?如何创建规则表以帮助我实现正确的计数?
一些样本:
CREATE TABLE `product` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`product_id` varchar(255) DEFAULT NULL,
`descr` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
insert into product (product_id, descr) values ('1','shrimp dish');
insert into product (product_id, descr) values ('2','beef dish');
insert into product (product_id, descr) values ('3','lobster dish');
insert into product (product_id, descr) values ('4','special1 dish');
CREATE TABLE `ticket` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`product_id` varchar(255) DEFAULT NULL,
`price` double DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
insert into ticket (product_id, price) values ('2',4);
insert into ticket (product_id, price) values ('3',6);
insert into ticket (product_id, price) values ('4',11);
在这里,我想查询一张票,让我得到总销售额(21美元),并且我卖了2x虾,2x龙虾(因为special1需要1x虾和1xlobster来制作)
答案 0 :(得分:1)
好吧,在列中进行操作要容易得多,请参阅my SQLfiddle here:
SELECT iname ingredient, SUM(amount) amount_used
FROM tickets
INNER JOIN products ON pid=tpid
INNER JOIN prodingred ON pi =pid
INNER JOIN ingredients ON iid=ii
GROUP BY iname
然而,你应该再引入两个表ingredients
和prodingred
,它们定义了哪种成分用于哪种菜肴。拥有适当的表将使整个事情比在CASE
语句中定义复杂的SELECT
结构更容易扩展。
我还在分配表amount
中引入了列prodingred
,您可以在其中为每个销售的产品放置实际金额(以g或kg为单位) 。这将使您的结果更准确,而不仅仅是说“我需要1只产品A的虾”。
<强>更新强>
如果您还希望查看每个使用成分的故障单的成本贡献,那么您想要将costshare
列添加到prodingred
表是一个好的开始点。如果您将此列设为浮点(或双列),您实际上可以表示每种食物(产品)中每种成分的成本份额,如下所示:
| pi | ii | amount | costshare |
|----|----|--------|-----------|
| 1 | 1 | 1 | 1 |
| 2 | 2 | 1 | 1 |
| 3 | 3 | 1 | 1 |
| 4 | 1 | 1 | 0.3 |
| 4 | 2 | 1 | 0.7 |
| 5 | 1 | 1 | 0.2 |
| 5 | 2 | 1 | 0.5 |
| 5 | 3 | 1 | 0.3 |
总结很简单:
SELECT iname ingredient, SUM(amount) amount_used,
SUM(ROUND(tprice*costshare*100)/100.) tprice_contribution
FROM tickets
INNER JOIN products ON pid=tpid
INNER JOIN prodingred ON pi =pid
INNER JOIN ingredients ON iid=ii
GROUP BY iname
哪个会帮到你(请参阅我的updated SQLfiddle)
| iname | amount_used | tprice_contribution |
|---------|-------------|---------------------|
| beef | 1 | 6 |
| lobster | 2 | 11.7 |
| shrimp | 1 | 3.3 |
答案 1 :(得分:0)
SELECT * FROM products;
+----------+ | name | +----------+ | shrimp | | lobster | | beef | | special1 | | special2 | +----------+
应用一些规则:
SELECT CASE WHEN name = 'shrimp' THEN 1 WHEN name = 'special1' THEN 1 WHEN name = 'special2' THEN 1 ELSE 0 END AS has_shrimp, CASE WHEN name = 'lobster' THEN 1 WHEN name = 'special1' THEN 1 WHEN name = 'special2' THEN 1 ELSE 0 END AS has_lobster, CASE WHEN name = 'beef' THEN 1 WHEN name = 'special2' THEN 1 ELSE 0 END AS has_beef FROM products;
+------------+-------------+----------+ | has_shrimp | has_lobster | has_beef | +------------+-------------+----------+ | 1 | 0 | 0 | | 0 | 1 | 0 | | 0 | 0 | 1 | | 1 | 1 | 0 | | 1 | 1 | 1 | +------------+-------------+----------+
计算上面的结果:
SELECT SUM(has_shrimp) AS shrimp_wentout, SUM(has_lobster) AS lobster_wentout, SUM(has_beef) AS beef_wentout FROM ( SELECT CASE WHEN name = 'shrimp' THEN 1 WHEN name = 'special1' THEN 1 WHEN name = 'special2' THEN 1 ELSE 0 END AS has_shrimp, CASE WHEN name = 'lobster' THEN 1 WHEN name = 'special1' THEN 1 WHEN name = 'special2' THEN 1 ELSE 0 END AS has_lobster, CASE WHEN name = 'beef' THEN 1 WHEN name = 'special2' THEN 1 ELSE 0 END AS has_beef FROM products ) AS tmp GROUP BY NULL;
+----------------+-----------------+--------------+ | shrimp_wentout | lobster_wentout | beef_wentout | +----------------+-----------------+--------------+ | 3 | 3 | 2 | +----------------+-----------------+--------------+