Mysql 查询每个产品的购买数量的产品列表

Mysql 查询每个产品的购买数量的产品列表,mysql,Mysql,我的MySQL没有其他人那么犀利,在过去的一个小时里我一直在努力解决这个问题。也许你能给我指出正确的方向。我有一份产品清单,我正试图从中得到一份报告。这就是我所拥有的: -- Product list: tbl_products id product_name ------ ---------------- 1 Hamburger 2 Cheeseburger 3 Burger Balls -- List of orders: tbl_

我的MySQL没有其他人那么犀利,在过去的一个小时里我一直在努力解决这个问题。也许你能给我指出正确的方向。我有一份产品清单,我正试图从中得到一份报告。这就是我所拥有的:

-- Product list: tbl_products
id       product_name
------  ----------------
1        Hamburger
2        Cheeseburger
3        Burger Balls


-- List of orders: tbl_orders
id       created
------  -----------------------
23       2013-09-04 00:00:00
45       2013-09-05 00:00:00
67       2013-09-09 00:00:00


-- Products bought per order: tbl_product_orders
order_id    product_id      quantity
----------  --------------  --------
23          1                4
23          2                6
45          1                1
67          3                2
这就是我试图通过一个查询实现的目标:

-- How do I get this
order_id    Hamburger     Cheeseburger    Burger Balls
----------  ------------- --------------- --------------
23           4             6               0
45           1             0               0
67           0             0               2
有人知道怎么做吗

编辑:
我将在稍后发布我以前的脚本。我现在只需要跑去上课。:)

您可以使用动态SQL来实现这一点

SET @sql = NULL;

SELECT GROUP_CONCAT(CONCAT('SUM(CASE WHEN product_id = ', id,
                           ' THEN quantity ELSE 0 END) `', product_name, '`'))
  INTO @sql
  FROM tbl_products;

SET @sql = CONCAT('SELECT order_id,', @sql,
                  '  FROM tbl_product_orders
                    GROUP BY order_id');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
输出:

| ORDER_ID | HAMBURGER | CHEESEBURGER | BURGER BALLS | |----------|-----------|--------------|--------------| | 23 | 4 | 6 | 0 | | 45 | 1 | 0 | 0 | | 67 | 0 | 0 | 2 |
下面是一个演示

您可以使用动态SQL完成它

SET @sql = NULL;

SELECT GROUP_CONCAT(CONCAT('SUM(CASE WHEN product_id = ', id,
                           ' THEN quantity ELSE 0 END) `', product_name, '`'))
  INTO @sql
  FROM tbl_products;

SET @sql = CONCAT('SELECT order_id,', @sql,
                  '  FROM tbl_product_orders
                    GROUP BY order_id');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
输出:

| ORDER_ID | HAMBURGER | CHEESEBURGER | BURGER BALLS | |----------|-----------|--------------|--------------| | 23 | 4 | 6 | 0 | | 45 | 1 | 0 | 0 | | 67 | 0 | 0 | 2 |
这里是演示

这将起作用,只有一个连接:

select order_id,
sum(if(product_orders.product_id=1, product_orders.quantity, 0)) as hamburglars,
sum(if(product_orders.product_id=2, product_orders.quantity, 0)) as cheese_burglars,
sum(if(product_orders.product_id=3, product_orders.quantity, 0)) as burglar_balls
from orders inner join product_orders on orders.id=product_orders.order_id
group by order_id

这将起作用,只有一个联接:

select order_id,
sum(if(product_orders.product_id=1, product_orders.quantity, 0)) as hamburglars,
sum(if(product_orders.product_id=2, product_orders.quantity, 0)) as cheese_burglars,
sum(if(product_orders.product_id=3, product_orders.quantity, 0)) as burglar_balls
from orders inner join product_orders on orders.id=product_orders.order_id
group by order_id


是的,你能做到。。???你能分享你的努力吗?试图在SQL中创建动态列通常不会有好的结果。选择您需要的数据并在应用程序中创建最终结果。不要使用动态列名,这不是sql的用途。如果您需要类似的东西,请查看XMLA或sql attrib模型。您可以这样做吗。。???你能分享你的努力吗?试图在SQL中创建动态列通常不会有好的结果。选择您需要的数据并在应用程序中创建最终结果。不要使用动态列名,这不是sql的用途。若您需要类似的东西,请使用动态sql查看XMLA或sql attrib modelsgo,或者使用XMLA。检查维基百科上的EAV模型这个答案有什么问题?它很好用。我是不是遗漏了什么?不是。工作正常,但如果在products表中添加一行,则不会在查询输出中自动创建新列。这不是一个要求,但杰克斯误解了。我也喜欢这个答案,因为它非常直截了当。如果我能选择两个答案,这肯定是另一个。谢谢!在BI中,您需要维护大量的例程,我喜欢保持列名不变,不管数据如何更改。在列中修复丢失的数据而其他数据都没有问题,比在早上发现例程由于错误而停止并且没有计算数据更容易;)然后使用动态sql,或者使用xmla。检查维基百科上的EAV模型这个答案有什么问题?它很好用。我是不是遗漏了什么?不是。工作正常,但如果在products表中添加一行,则不会在查询输出中自动创建新列。这不是一个要求,但杰克斯误解了。我也喜欢这个答案,因为它非常直截了当。如果我能选择两个答案,这肯定是另一个。谢谢!在BI中,您需要维护大量的例程,我喜欢保持列名不变,不管数据如何更改。在列中修复丢失的数据而其他数据都没有问题,比在早上发现例程由于错误而停止并且没有计算数据更容易;)效果很好。我以前从未使用过存储过程,因此这是一个真正的大开眼界。是
DEALLOCATE PREPARE stmt
真的需要吗?@enchance它在没有
DEALLOCATE
的情况下可以工作,但如果您不再需要准备好的语句,您最好使用它。否则
stmt
将一直有效,直到会话终止。效果很好。我以前从未使用过存储过程,因此这是一个真正的大开眼界。是
DEALLOCATE PREPARE stmt
真的需要吗?@enchance它在没有
DEALLOCATE
的情况下可以工作,但如果您不再需要准备好的语句,您最好使用它。否则,
stmt
将一直有效,直到会话终止。