如何在一个案例中多次计算一行

时间:2015-09-15 04:46:33

标签: mysql sql

产品表:

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来制作)

2 个答案:

答案 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

然而,你应该再引入两个表ingredientsprodingred,它们定义了哪种成分用于哪种菜肴。拥有适当的表将使整个事情比在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 |
+----------------+-----------------+--------------+