Sql行转列的两个小例子

SQL行转列

所谓行转列就是将某一个category类型的列(nx1的矩阵,实质是有m类),目标是将多行转换成为多列(新增m列)。

  1. 例1:模拟顺丰SQL小例子
##顺丰面试题(SQLite编码实现题目)
import sqlite3
conn=sqlite3.connect('C:/Users/Administrator/Kaggle_in/SQLite/country_state.sqlite')
curs=conn.cursor()
curs.execute('create table waybill_constype(Consign_day int,waybill_no int,Class varchar(20),Userid varchar(20))')
curs.execute("insert into waybill_constype(Consign_day,waybill_no,Class,Userid) values(20180401,755200201,'文件','A001')")
curs.execute("insert into waybill_constype(Consign_day,waybill_no,Class,Userid) values(20180403,755200202,'娱乐','A001')")
curs.execute("insert into waybill_constype(Consign_day,waybill_no,Class,Userid) values(20180405,755200203,'食品','A001')")
curs.execute("insert into waybill_constype(Consign_day,waybill_no,Class,Userid) values(20180407,755299911,'文件','A001')")
curs.execute("insert into waybill_constype(Consign_day,waybill_no,Class,Userid) values(20180401,755200204,'娱乐','A003')")
curs.execute("insert into waybill_constype(Consign_day,waybill_no,Class,Userid) values(20180401,755200205,'文件','')")
curs.execute("insert into waybill_constype(Consign_day,waybill_no,Class,Userid) values(20180401,755200207,'食品','A002')")
curs.execute("insert into waybill_constype(Consign_day,waybill_no,Class,Userid) values(20180411,755288819,'文件','A002')")
curs.execute("insert into waybill_constype(Consign_day,waybill_no,Class,Userid) values(20180401,755200247,'食品','A002')")
curs.execute("insert into waybill_constype(Consign_day,waybill_no,Class,Userid) values(20180401,755200241,'文件','A003')")
curs.execute("insert into waybill_constype(Consign_day,waybill_no,Class,Userid) values(20180403,755200232,'娱乐','A003')")
curs.execute("insert into waybill_constype(Consign_day,waybill_no,Class,Userid) values(20180405,755200233,'食品','A003')")
curs.execute("insert into waybill_constype(Consign_day,waybill_no,Class,Userid) values(20180507,755299931,'文件','A004')")
curs.execute("insert into waybill_constype(Consign_day,waybill_no,Class,Userid) values(20180501,755200234,'娱乐','A003')")
curs.execute("insert into waybill_constype(Consign_day,waybill_no,Class,Userid) values(20180501,755200235,'文件','')")
curs.execute("insert into waybill_constype(Consign_day,waybill_no,Class,Userid) values(20180501,755200237,'食品','A004')")
curs.execute("insert into waybill_constype(Consign_day,waybill_no,Class,Userid) values(20180511,755288829,'文件','A002')")
curs.execute("insert into waybill_constype(Consign_day,waybill_no,Class,Userid) values(20180501,755200217,'食品','A002')")
curs.execute("insert into waybill_constype(Consign_day,waybill_no,Class,Userid) values(20190401,755200234,'娱乐','A003')")
curs.execute("insert into waybill_constype(Consign_day,waybill_no,Class,Userid) values(20190401,755200235,'文件','')")
curs.execute("insert into waybill_constype(Consign_day,waybill_no,Class,Userid) values(20190401,755200237,'食品','A004')")
curs.execute("insert into waybill_constype(Consign_day,waybill_no,Class,Userid) values(20190411,755288829,'文件','A002')")
curs.execute("insert into waybill_constype(Consign_day,waybill_no,Class,Userid) values(20190421,755200217,'食品','A002')")

curs.execute("insert into waybill_constype(Consign_day,waybill_no,Class,Userid) values(20180405,755200233,'衣物','A003')")
curs.execute("insert into waybill_constype(Consign_day,waybill_no,Class,Userid) values(20180507,755299931,'托运','A004')")
curs.execute("insert into waybill_constype(Consign_day,waybill_no,Class,Userid) values(20180501,755200234,'衣物','A003')")
curs.execute("insert into waybill_constype(Consign_day,waybill_no,Class,Userid) values(20180501,755200235,'托运','A001')")
curs.execute("insert into waybill_constype(Consign_day,waybill_no,Class,Userid) values(20180501,755200237,'食品','A004')")
curs.execute("insert into waybill_constype(Consign_day,waybill_no,Class,Userid) values(20180511,755288829,'衣物','A002')")
curs.execute("insert into waybill_constype(Consign_day,waybill_no,Class,Userid) values(20180501,755200217,'托运','A002')")
curs.execute("insert into waybill_constype(Consign_day,waybill_no,Class,Userid) values(20190401,755200234,'衣物','A003')")
curs.execute("insert into waybill_constype(Consign_day,waybill_no,Class,Userid) values(20190401,755200235,'托运','A003')")
curs.execute("insert into waybill_constype(Consign_day,waybill_no,Class,Userid) values(20190401,755200237,'食品','A004')")
curs.execute("insert into waybill_constype(Consign_day,waybill_no,Class,Userid) values(20190411,755288829,'文件','A002')")
curs.execute("insert into waybill_constype(Consign_day,waybill_no,Class,Userid) values(20190421,755200217,'托运','A002')")

curs.execute("SELECT * FROM waybill_constype")
data2=curs.fetchall()
print(data2)

结果:

[(20180401, 755200201, '文件', 'A001'), (20180403, 755200202, '娱乐', 'A001'), 
(20180405, 755200203, '食品', 'A001'), (20180407, 755299911, '文件', 'A001'),
(20180401, 755200204, '娱乐', 'A003'), (20180401, 755200205, '文件', ''),
(20180401, 755200207, '食品', 'A002'), (20180411, 755288819, '文件', 'A002'),
(20180401, 755200207, '食品', 'A002'), (20180411, 755288819, '文件', 'A002'), 
(20180401, 755200247, '食品', 'A002'), (20180401, 755200241, '文件', 'A003'),
(20180403, 755200232, '娱乐', 'A003'), (20180405, 755200233, '食品', 'A003'), 
(20180507, 755299931, '文件', 'A004'), (20180501, 755200234, '娱乐', 'A003'), 
(20180501, 755200235, '文件', ''), (20180501, 755200237, '食品', 'A004'), 
(20180511, 755288829, '文件', 'A002'), (20180501, 755200217, '食品', 'A002'), 
(20190401, 755200234, '娱乐', 'A003'), (20190401, 755200235, '文件', ''),
(20190401, 755200237, '食品', 'A004'), (20190411, 755288829, '文件', 'A002'), 
(20190421, 755200217, '食品', 'A002'), (20180405, 755200233, '衣物', 'A003'), 
(20180507, 755299931, '托运', 'A004'), (20180501, 755200234, '衣物', 'A003'), 
(20180501, 755200235, '托运', 'A001'), (20180501, 755200237, '食品', 'A004'), 
(20180511, 755288829, '衣物', 'A002'), (20180501, 755200217, '托运', 'A002'), 
(20190401, 755200234, '衣物', 'A003'), (20190401, 755200235, '托运', 'A003'),
(20190401, 755200237, '食品', 'A004'), (20190411, 755288829, '文件', 'A002'),
 (20190421, 755200217, '托运', 'A002')]
#1.1.1选出各个会员在揽收的文化、娱乐、食品的件数揽件类型:
curs.execute("SELECT Userid,count(Userid)  FROM waybill_constype group by Userid")
data3=curs.fetchall()

curs.execute("SELECT Userid,Class,count(Userid)  FROM waybill_constype group by Userid,Class")
data3=curs.fetchall()
print(data3)

结果

[('', '文件', 3), ('A001', '娱乐', 1), ('A001', '托运', 1), ('A001', '文件', 2), 
('A001', '食品', 1), ('A002', '托运', 2), ('A002', '文件', 5), ('A002', '衣物', 1),
 ('A002', '食品', 5), ('A003', '娱乐', 4), ('A003', '托运', 1), ('A003', '文件', 1),
  ('A003', '衣物', 3), ('A003', '食品', 1), ('A004', '托运', 1), ('A004', '文件', 1),
   ('A004', '食品', 4)]
##1.1.2选出各个会员在month=4月份(加区间)的揽收的文化、娱乐、食品的件数揽件类型:
curs.execute("SELECT Userid,Class,count(Userid)  FROM waybill_constype 
where  Consign_day between 20180401 and 20180430 
group by Userid,Class")
data3=curs.fetchall()
print(data3)

结果

[('', '文件', 1),
('A001', '娱乐', 1),
('A001', '文件', 2),
('A001', '食品', 1),
('A002', '文件', 2), 
('A002', '食品', 3), 
('A003', '娱乐', 2),
('A003', '文件', 1),
('A003', '衣物', 1),
('A003', '食品', 1)]

=华丽的分割线==
想要将上面的结果做行转列

#1.1.4.行列转换
#1.1.4.1.先处理成行转列前的数据形式 as target:
#(SELECT Userid,Class,count(Userid) as total FROM waybill_constype \
#where  Consign_day between 20180401 and 20180430  \
#group by Userid,Class)
#1.1.4.2.将:target表中的目标对象列Class从多行(nx1)转变为成为多列(1xm,m为category的类别数):
#因为Class中主要是:'娱乐','文件','食品',m=5===>容易推出m=100时这里写100句sum语句即可;m=12表示月份需要些12句sum语句。
curs.execute("SELECT Userid, \
sum(CASE WHEN Class='娱乐' THEN total ELSE 0 END) AS '娱乐', \
sum(CASE WHEN Class='文件' THEN total ELSE 0 END) AS '文件', \
sum(CASE WHEN Class='食品' THEN total ELSE 0 END) AS '食品',\
sum(CASE WHEN Class='衣物' THEN total ELSE 0 END) AS '衣物',\
sum(CASE WHEN Class='托运' THEN total ELSE 0 END) AS '托运'\
from (SELECT Userid,Class,count(Userid) as total FROM waybill_constype \
where  Consign_day/100%10==4  \
group by Userid,Class)\
group by Userid") #会自动按UserID升序来排列
data3=curs.fetchall()
print(data3)

结果

Userid,娱乐,文件,食品,衣物,托运
[('', 0, 2, 0, 0, 0), 
('A001', 1, 2, 1, 0, 0),
('A002', 0, 4, 4, 0, 1), 
('A003', 3, 1, 1, 2, 1), 
('A004', 0, 0, 2, 0, 0)]

问题:上述日期是整型变量,现在改为str和date类型做测试

#split()分割后返回的一个list
'2018-04-24'.split('-')[0]
'2018-04-24'.split('-')[1]
'2018-04-24'.split('-')[2]


##对date类型的数据的探索和补充
curs.execute('create table LMS_TJPC_NORMAL1(zldwdm varchar(20),dl_bm date,gqmj double(10))')
curs.execute("insert into LMS_TJPC_NORMAL1(zldwdm,dl_bm,gqmj) values('220882001001','2018-04-20',240)")
curs.execute("insert into LMS_TJPC_NORMAL1(zldwdm,dl_bm,gqmj) values('220882001002','2018-04-12',140)")
curs.execute("insert into LMS_TJPC_NORMAL1(zldwdm,dl_bm,gqmj) values('220882001003','2018-05-20',200)")

#针对date时间的选取过程,使用substr(strftime(time)))的嵌套
curs.execute("select * from LMS_TJPC_NORMAL1")
data4=curs.fetchall()
curs.execute("update LMS_TJPC_NORMAL1 set dl_bm='2018-04-20 20:40:40'")
curs.execute("select * from LMS_TJPC_NORMAL1 where strftime('%m',dl_bm)==4")
curs.execute("select * from LMS_TJPC_NORMAL1 where substr(strftime('%Y.%m.%d %H:%M:%S',dl_bm),8,-2)=='04'")
data4=curs.fetchall()
  1. 例2:模拟将月份做行转列的L小例子

curs.execute('create table LMS_TJPC_NORMAL(zldwdm varchar(20),dl_bm varchar(3),gqmj double(10))')
curs.execute("insert into LMS_TJPC_NORMAL(zldwdm,dl_bm,gqmj) values('220882001001','01',240)")
curs.execute("insert into LMS_TJPC_NORMAL(zldwdm,dl_bm,gqmj) values('220882001001','01',100.58)")

curs.execute("insert into LMS_TJPC_NORMAL(zldwdm,dl_bm,gqmj) values('220882001001','02',7.96)")
curs.execute("insert into LMS_TJPC_NORMAL(zldwdm,dl_bm,gqmj) values('220882001001','03',25)")
curs.execute("insert into LMS_TJPC_NORMAL(zldwdm,dl_bm,gqmj) values('220882001001','03',2.65)")

curs.execute("insert into LMS_TJPC_NORMAL(zldwdm,dl_bm,gqmj) values('220882001001','04',1.65)")
curs.execute("insert into LMS_TJPC_NORMAL(zldwdm,dl_bm,gqmj) values('220882001001','10',29.34)")

curs.execute("insert into LMS_TJPC_NORMAL(zldwdm,dl_bm,gqmj) values('220882001001','11',12.61)")
curs.execute("insert into LMS_TJPC_NORMAL(zldwdm,dl_bm,gqmj) values('220882001001','12',6.72)")
curs.execute("insert into LMS_TJPC_NORMAL(zldwdm,dl_bm,gqmj) values('220882001001','20',754.25)")
curs.execute("insert into LMS_TJPC_NORMAL(zldwdm,dl_bm,gqmj) values('220882001001','01',345.53)")

curs.execute("insert into LMS_TJPC_NORMAL(zldwdm,dl_bm,gqmj) values('220882001002','02',7.96)")
curs.execute("insert into LMS_TJPC_NORMAL(zldwdm,dl_bm,gqmj) values('220882001002','03',25)")
curs.execute("insert into LMS_TJPC_NORMAL(zldwdm,dl_bm,gqmj) values('220882001002','03',2.65)")

curs.execute("insert into LMS_TJPC_NORMAL(zldwdm,dl_bm,gqmj) values('220882001002','04',1.65)")
curs.execute("insert into LMS_TJPC_NORMAL(zldwdm,dl_bm,gqmj) values('220882001002','10',29.34)")

curs.execute("insert into LMS_TJPC_NORMAL(zldwdm,dl_bm,gqmj) values('220882001002','11',12.61)")
curs.execute("insert into LMS_TJPC_NORMAL(zldwdm,dl_bm,gqmj) values('220882001002','12',6.72)")
curs.execute("insert into LMS_TJPC_NORMAL(zldwdm,dl_bm,gqmj) values('220882001002','20',754.25)")
curs.execute("insert into LMS_TJPC_NORMAL(zldwdm,dl_bm,gqmj) values('220882001002','01',345.53)")
#选取子串函数substr()
curs.execute("select substr(zldwdm,11,12) as zldwdm,dl_bm as dlbm,sum(gqmj) as mj from LMS_TJPC_NORMAL GROUP BY substr(zldwdm,11,12),dl_bm")
data4=curs.fetchall()
print(data4)

结果

[('01', '01', 686.110), ('01', '02', 7.96), ('01', '03', 27.65), ('01', '04', 1.65),
 ('01', '10', 29.34), ('01', '11', 12.61), ('01', '12', 6.72), ('01', '20', 754.25), 
 ('02', '01', 345.53), ('02', '02', 7.96), ('02', '03', 27.65), ('02', '04', 1.65), 
 ('02', '10', 29.34), ('02', '11', 12.61), ('02', '12', 6.72), ('02', '20', 754.25)]

####行转列开始####

#数据的多行转多列:
curs.execute("SELECT zldwdm,sum(mj) as total,\
sum(CASE WHEN dlbm='01' THEN mj ELSE 0 END) AS '01', \
sum(CASE WHEN dlbm='02' THEN mj ELSE 0 END) AS '02', \
sum(CASE WHEN dlbm='03' THEN mj ELSE 0 END) AS '03', \
sum(CASE WHEN dlbm='04' THEN mj ELSE 0 END) AS '04', \
sum(CASE WHEN dlbm='20' THEN mj ELSE 0 END) AS '20', \
sum(CASE WHEN dlbm='10' THEN mj ELSE 0 END) AS '10', \
sum(CASE WHEN dlbm='11' THEN mj ELSE 0 END) AS '11', \
sum(CASE WHEN dlbm='12' THEN mj ELSE 0 END) AS '12'  \
from (select  zldwdm,substr(dl_bm,1,2) as dlbm,sum(gqmj) as mj  \
from LMS_TJPC_NORMAL  \
group by zldwdm,substr(dl_bm,1,2)) \
GROUP BY zldwdm")
data4=curs.fetchall()
print(data4)

结果

编号,01,02,03,04,20,10,11,12
[('220882001001', 1526.29, 686.1099999999999, 7.96, 27.65, 1.65, 754.25, 29.34, 12.61, 6.72), 
('220882001002', 1185.71, 345.53, 7.96, 27.65, 1.65, 754.25, 29.34, 12.61, 6.72)]

猜你喜欢

转载自blog.csdn.net/jp_zhou256/article/details/83047062