简体   繁体   English

带有月列和多个字段行的mysql交叉表

[英]mysql crosstab with month columns and multiple field rows

Creating monthly sales summary for different products. 创建不同产品的每月销售摘要。 Zane Bien post here very helpful in creating query to produce one row for a single product: Zane Bien在此处发布的文章对于创建查询以为单个产品生成一行非常有帮助:

Income Source  Jan   Feb   Mar   --  Total  Pct  
Report Fees    11285 12745 17980 ... 236970 95.9954

Here is that query: 这是该查询:

SELECT "Report Fees" AS `Income Source`, 
SUM( IF( MONTH( b.ord_billed_time ) =1, b.ord_fee_report, 0 ) ) AS Jan, 
SUM( IF( MONTH( b.ord_billed_time ) =2, b.ord_fee_report, 0 ) ) AS Feb, 
SUM( IF( MONTH( b.ord_billed_time ) =3, b.ord_fee_report, 0 ) ) AS Mar, 
"..." AS `--` , 
SUM( b.ord_fee_report ) AS Total, 
AVG( b.ord_fee_report / b.ord_fee_total ) *100 AS Pct
FROM orders b
WHERE b.ord_billed_time IS NOT NULL 
AND b.ord_cancelled_time IS NULL 
AND b.ord_fee_report IS NOT NULL 
AND year( b.ord_billed_time ) = 2012
AND b.clientID = 8 

Is there a way to expand this single query so that I get 8 rows, one for each different income type, and a "grand total" line? 有没有一种方法可以扩展此单个查询,以使我得到8行,每种收入类型各占一行,以及“总计”行? Something like this: 像这样:

Income Source  Jan   Feb   Mar   --  Total  Pct  
Report Fees    11285 12745 17980 ... 236970 95.9954
Income Type2    5401  3320  1394 ...  13456  0.321
Income Type3      98   421    14 ...   1102  0.001
...
Total         333333 22222 11111 ... 9999999 100.0

The income types are stored in the orders table in separate columns: ord_fee_x, ord_fee_y, ord_fee_z, etc. 收入类型存储在订单表的单独列中:ord_fee_x,ord_fee_y,ord_fee_z等。

Right now I'm running 8 queries and loading results into an array, then displaying from that array. 现在,我正在运行8个查询并将结果加载到数组中,然后从该数组中显示。 Just seems more efficient to get data all at one time and display row by row as returned. 一次获取所有数据并按行显示返回的结果似乎更有效率。

Is there a way to do that? 有没有办法做到这一点?

It is possible through the UNION operation. 通过UNION操作是可能的。 Ideally, you should use UNION ALL for your situation as it appears that your queries will produce unique results based off the custom calculations for each income source. 理想情况下,应根据情况使用UNION ALL ,因为您的查询似乎将根据每个收入来源的自定义计算产生唯一的结果。 UNION ALL will include all rows which is arguably faster in comparison to UNION , which excludes duplicate rows. UNION ALL将包含所有行,而UNION排除了重复的行,这可以说是更快的。

In other words: 换一种说法:

(SELECT "Report Fees" AS `Income Source`, 
SUM( IF( MONTH( b.ord_billed_time ) =1, b.ord_fee_report, 0 ) ) AS Jan, 
SUM( IF( MONTH( b.ord_billed_time ) =2, b.ord_fee_report, 0 ) ) AS Feb, 
SUM( IF( MONTH( b.ord_billed_time ) =3, b.ord_fee_report, 0 ) ) AS Mar, 
"..." AS `--` , 
SUM( b.ord_fee_report ) AS Total, 
AVG( b.ord_fee_report / b.ord_fee_total ) *100 AS Pct
FROM orders b
WHERE b.ord_billed_time IS NOT NULL 
AND b.ord_cancelled_time IS NULL 
AND b.ord_fee_report IS NOT NULL 
AND year( b.ord_billed_time ) = 2012
AND b.clientID = 8)
UNION ALL
(... query 2 ...)
UNION ALL
(... query 3 ...)

and so forth. 等等。

Reference : http://dev.mysql.com/doc/refman/5.0/en/union.html 参考http : //dev.mysql.com/doc/refman/5.0/en/union.html

Thanks, Daniel. 谢谢,丹尼尔。
I was hoping for a CASE or similar solution that would be more code efficient, but guess that's not an option. 我希望有一个CASE或类似的解决方案,它可以提高代码效率,但是我猜这不是一个选择。 Will save me creating a bunch of arrays, though. 不过,这将节省我创建一堆数组的时间。 Bruce 布鲁斯

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM