Mysql 行列转换
一、第一种
原数据表

转换后

DROP TABLE IF EXISTS tempdynamic;
CREATE TEMPORARY TABLE tempdynamic (
SELECT p.fsPaymentName,sr.fsPaymentId,sh.fsShiftName,SUM(sr.fdReceMoney) as AmtTotal FROM tbsell as s
INNER JOIN tbSellReceive as sr ON s.fsSellNo=sr.fsSellNo AND s.fsShopGUID=sr.fsShopGUID
INNER JOIN tbpayment as p on sr.fsPaymentId =p.fsPaymentId and p.fsShopGUID=s.fsShopGUID and p.fiStatus=1
INNER JOIN tbSellCheck as sc on sc.fsSellNo=s.fsSellNo AND s.fsShopGUID=sc.fsShopGUID
INNER JOIN tbshift as sh ON sc.fsShiftId=sh.fsShiftId AND sh.fiStatus=1
WHERE s.fiBillStatus=3
AND s.fsShopGUID='c5f0d5c9d8b349f493c180bcc22d9ce0'
AND s.fsSellDate='2016-01-15'
GROUP BY sr.fsPaymentId,sc.fsShiftId); SET @EE='';
set @str_tmp=''; SELECT @EE:=CONCAT(@EE,'SUM(IF(fsShiftName=\'',fsShiftName,'\'',',AmtTotal,0)) AS ',fsShiftName,',') as aa into @str_tmp
FROM (
SELECT DISTINCT fsShiftName from tempdynamic
) A order by length(aa) desc limit 1; SET @QQ=CONCAT('SELECT ifnull(fsPaymentName,\'total\') as 科目名称 ,',@str_tmp,' SUM(AmtTotal) as 合计 FROM tempdynamic Group by fsPaymentName WITH ROLLUP'); PREPARE stmt FROM @QQ;
EXECUTE stmt ;
deallocate prepare stmt;
二、第二种
原数据表

转换后

DROP TABLE IF EXISTS tempdynamic;
CREATE TABLE tempdynamic (
SELECT sh.fsShiftName,sh.fsShiftId, SUM(s.fdSaleAmt) as 销售金额,SUM(s.fdDiscountAmt) as 折扣金额, SUM(s.fdServiceAmt) as 服务费金额,SUM(s.fdExpAmt) as 应收金额 ,SUM(s.fdRealAmt) as 实收金额
FROM tbsell as s
INNER JOIN tbSellCheck as sc on sc.fsSellNo=s.fsSellNo AND s.fsShopGUID=sc.fsShopGUID
INNER JOIN tbshift as sh ON sc.fsShiftId=sh.fsShiftId AND sh.fiStatus=1
WHERE s.fiBillStatus=3
AND s.fsShopGUID='c5f0d5c9d8b349f493c180bcc22d9ce0'
AND s.fsSellDate='2016-01-15'
GROUP BY sc.fsShiftId); DROP TABLE IF EXISTS tempdynamica;
CREATE TEMPORARY TABLE tempdynamica(
SELECT a.* FROM (
SELECT fsShiftName,'销售金额' AS 科目,销售金额 AS AmtTotal FROM tempdynamic UNION ALL
SELECT fsShiftName,'折扣金额' AS 科目,折扣金额 AS AmtTotal FROM tempdynamic UNION ALL
SELECT fsShiftName,'服务费金额' AS 科目,服务费金额 AS AmtTotal FROM tempdynamic UNION ALL
SELECT fsShiftName,'应收金额' AS 科目,应收金额 AS AmtTotal FROM tempdynamic UNION ALL
SELECT fsShiftName,'实收金额' AS 科目,实收金额 AS AmtTotal FROM tempdynamic
ORDER BY fsShiftName,科目 DESC) as a ); SET @EE='';
set @str_tmp='';
SELECT @EE:=CONCAT(@EE,'SUM(IF(fsShiftName=\'',fsShiftName,'\'',',AmtTotal ,0)) AS ',fsShiftName,',') as aa into @str_tmp
FROM (
SELECT DISTINCT fsShiftName from tempdynamic
) A order by length(aa) desc limit 1;
SET @QQ=CONCAT('SELECT ifnull(科目,\'total\') as 科目名称,',@str_tmp,'sum(AmtTotal) as 合计 FROM tempdynamica Group by 科目 WITH ROLLUP');
PREPARE stmt FROM @QQ;
EXECUTE stmt ;
deallocate prepare stmt;
postgresql
原数据:

转换后:

sql:
CREATE OR REPLACE FUNCTION "public"."test"()
RETURNS "pg_catalog"."void" AS $BODY$
DECLARE
dynsql1 VARCHAR ;
dynsql2 VARCHAR ;
dynsql3 VARCHAR ;
BEGIN
drop table if exists temp_sell;
dynsql1='CREATE TEMP TABLE temp_sell AS SELECT
bd.area_id,
bd.area_name,
bd.sell_date,
SUM (
COALESCE (bss.original_amt, 0)
) AS original_amt
FROM
bill_detail AS bd
INNER JOIN bill_settlement_summary AS bss ON bd.bill_id = bss.bill_id
WHERE
bd.sell_date BETWEEN ''2018-01-01''
AND ''2018-01-30''
AND bd.shop_guid=''143174''
-- AND area_id=''''
-- AND msection_id=''''
GROUP BY
bd.sell_date,
bd.area_id,
bd.area_name;';
EXECUTE dynsql1;
dynsql2 = '';
dynsql3 = '';
drop table if exists temp_sell_1;
CREATE TEMP TABLE temp_sell_1 AS
SELECT concat('SUM(CASE WHEN sell_date=''',sell_date,'''','then original_amt else 0 end) AS "',sell_date,'"') AS aa
FROM
(SELECT DISTINCT
sell_date
FROM
temp_sell) A
ORDER BY sell_date ASC ;
SELECT string_agg(aa, ',') INTO dynsql2 from temp_sell_1;
RAISE NOTICE 'dynsql2==[%]', dynsql2 ;
dynsql3 = CONCAT(
'SELECT area_id as 区域id,area_name as 区域名称,' ,dynsql2,
',sum(original_amt) 汇总 FROM temp_sell Group By area_id,area_name;'
);
RAISE NOTICE 'dynsql3==[%]', dynsql3 ;
END ;
$BODY$
LANGUAGE 'plpgsql' VOLATILE COST 100
;
SELECT test();
SELECT area_id as 区域id,area_name as 区域名称,SUM(CASE WHEN sell_date='2018-01-12'then original_amt else 0 end) AS "2018-01-12",SUM(CASE WHEN sell_date='2018-01-18'then original_amt else 0 end) AS "2018-01-18",SUM(CASE WHEN sell_date='2018-01-19'then original_amt else 0 end) AS "2018-01-19",SUM(CASE WHEN sell_date='2018-01-25'then original_amt else 0 end) AS "2018-01-25",sum(original_amt) 汇总 FROM temp_sell Group By area_id,area_name;
第二种方案:
参考: http://www.cureffi.org/2013/03/19/automatically-creating-pivot-table-column-names-in-postgresql/
使用函数如下:
CREATE OR REPLACE FUNCTION "public"."pivotcode"("tablename" varchar, "rowc" varchar, "rowctype" varchar, "groupby" varchar, "colc" varchar, "cellc" varchar, "celldatatype" varchar)
RETURNS "pg_catalog"."void" AS $BODY$
DECLARE rec record ; dynsql1 VARCHAR ; dynsql2 VARCHAR ; countrows INT; columnlist VARCHAR ;
BEGIN
drop table if exists temp_sell_result;
dynsql1 = 'select count(1) from ' || tablename || ';' ;
EXECUTE dynsql1 INTO countrows ;
IF countrows=0 THEN
dynsql1='CREATE TEMP TABLE temp_sell_result AS select * from ' || tablename || ';';
EXECUTE dynsql1;
ELSE
-- 1. retrieve list of column names.
dynsql1 = 'select string_agg(distinct ''"''||' || colc || '||''" ' || celldatatype || ''','','' order by ''"''||' || colc || '||''" ' || celldatatype || ''') from ' || tablename || ';' ;
--RAISE NOTICE '%', dynsql1 ;
EXECUTE dynsql1 INTO columnlist ;
-- 2. set up the crosstab query
dynsql2 = 'CREATE TEMP TABLE temp_sell_result AS select * from crosstab (
''select ' || rowc || ',' || colc || ',' || cellc || ' from ' || tablename || ' group by '||groupby||' order by '||groupby||''',
''select distinct ' || colc || ' from ' || tablename || ' order by 1''
)
as newtable (
' || rowctype || ',' || columnlist || '
);' ;
EXECUTE dynsql2 ;
END IF;
END ;
$BODY$
LANGUAGE 'plpgsql' VOLATILE COST 100
;
ALTER FUNCTION "public"."pivotcode"("tablename" varchar, "rowc" varchar, "rowctype" varchar, "groupby" varchar, "colc" varchar, "cellc" varchar, "celldatatype" varchar) OWNER TO "winposdev";
Mysql 行列转换的更多相关文章
- 【学亮IT手记】MySql行列转换案例
create table score( name ), math int, english int ); ,); ,); ,); ,); SHOW tables; SELECT * from scor ...
- MySQL行列转换
分类: Mysql/postgreSQL 在某些数据库中有交叉表,但在MySQL中却没有这个功能,但网上看到有不少朋友想找出一个解决方法,特发贴集思广义.http://topic.csdn.net/u ...
- MySQL行列转换拼接
mysql> select TBL_ID,CREATE_TIME,LAST_ACCESS_TIME,TBL_NAME,TBL_TYPE from TBLS; +--------+-------- ...
- 【转载】mysql行列转换方法总结
[转载]mysql行列转换方法总结 [MySQL] 行列转换变化各种方法实现总结(行变列报表统计.列变行数据记录统计等) Mysql 列转行统计查询 .行转列统计查询 在某些数据库中有交叉表,但在My ...
- Mysql实现行列转换
前言: 最近又玩起了sql语句,想着想着便给自己出了一道题目:“行列转换”.起初瞎折腾了不少时间也上网参考了一些博文,不过大多数是采用oracle数据库当中的一些便捷函数进行处理,比如”pivot”. ...
- mysql:sql行列转换
今天一个同学遇到一个问题问我了,由于本人平时学习的mysql比较基础,确实没解决,后来google了一下,才知道是sql的一种技法[行列转换],话不多说先上图: 想得到下面的结果: +------+- ...
- MySQL中行列转换的SQL技巧
行列转换常见场景 由于很多业务表因为历史原因或者性能原因,都使用了违反第一范式的设计模式.即同一个列中存储了多个属性值(具体结构见下表). 这种模式下,应用常常需要将这个列依据分隔符进行分割,并得到列 ...
- mysql 行列动态转换(列联表,交叉表)
mysql 行列动态转换(列联表,交叉表) (1)动态,适用于列不确定情况 create table table_name( id int primary key, col1 char(2), col ...
- 简单的叙述下SQL中行列转换的小知识!
行列转换对于工作还是学习中总是不可避免的会遇到(虽然本人还尚未工作,萌萌哒的学生一枚),解决的方法也有很多,我这里就总结一下我所想解决的问题以及怎么去解决的方法, 可能网上已经有很多类似的方法了,有的 ...
随机推荐
- MFC注册窗口类以及FindWindow按窗口类名查询
很多玩游戏的人都知道一般游戏客户端程序是不允许双开的,就是说在同一游戏在启动的时候,是无法打开多个窗口.很多其他软件如酷狗播放器等也是这样.如果把打开的窗口最小化,这时重新启动程序,最小化的窗口会被显 ...
- locate 最快的查找文件的命令 NB
我见过最NB的查找文件最快的命令 [root@NB data]# locate teamviewer. /data/Software/teamviewer.i686.rpm /home/ok/.loc ...
- struts 2 时间控件
在使用struts2框架时,为我们提供了时间选择器控件:datetimepicker.但是在使用过程中会出现一些问题,主要就是struts2版本更新时做了一些修改.在struts2.0时,使用< ...
- 【leetcode】Remove Nth Node From End of List
题目简述: Given a linked list, remove the nth node from the end of list and return its head. For example ...
- 【leetcode】Intersection of Two Linked Lists
题目简述: Write a program to find the node at which the intersection of two singly linked lists begins. ...
- 友盟推送 .NET (C#) 服务端 SDK rest api 调用库
友盟推送 .NET SDK rest api 介绍 该版本是基于友盟推送2.3版本封装的,网上查询了下发现没有.NET版本的调用库,官方也没有封装.NET的版本,只有python.java.php版本 ...
- CozyRSS开发记录20-CanResizeWithGrip
CozyRSS开发记录20-CanResizeWithGrip 1.窗口样式 首先,WindowStyle有四种: 然后,对于窗口缩放的ResizeMode,也有四种,CanResize和CanRes ...
- Git 简介
版本控制 什么是版本控制? 我需要版本控制吗? - 如果你还没使用过版本控制系统,或许你会有以上疑问,甚至更多疑问.希望后面的回答能让你喜欢上版本控制系统,喜欢上Git. 什么是版本控制:顾名思义,版 ...
- Asp.net mvc页面传值-- dropdownlist
后台传值 List<ConfigParamInfo> paramList = configParamBLL.GetModelList(" and parentID=1" ...
- mysql开启远程访问权限
1. //登录数据库 mysql -u root -pvmwaremysql>use mysql; //%为所有ip都可以远程访问 mysql>update user set host = ...