行轉列的應用
快到聖誕節了,需求弄出了一堆活動
其中一個活動要求使用者每天簽到,連續若干天,有不同級別的獎勵.
簽到表模擬如下,userid記錄使用者的ID,createtime模擬使用者簽到的時間.
其中nums是數字輔助表,用法參見
http://blog.itpub.net/29254281/viewspace-1362897/
上面的SQL模擬了一批使用者的簽到資料.
程式研發都已經做完了,需求拿了一個excel模板,讓我統計每天的每小時使用者簽到情況.
這個應該是行轉列的一個典型應用吧
一會兒需求又來了,說是中間缺資料啊.沒有18點,21點的資料啊.
我解釋了半天,說是那幾個時間點,沒有使用者簽到.
人家需求不管,說是沒有使用者簽到的時間段,可以補成0.
(最近天天加班,心情不好,當時真想掐死她..)
不過其實也不難.使用數字輔助表就可以了.
好了,沒有使用者簽到的時間段也填充了0
剛做完,新需求又來了,“統計每天的使用者簽到資料和每天的增量資料”..好吧
透過左連線,求得兩天內的簽到差值,然後union當天的簽到資料,最後再行轉列.
他的增量資料是這個意思,比如16日4人簽到,17日5人簽到,那麼17日的增量資料為1.
當然,如果15日的簽到人數為5,16日的簽到人數為4,那麼16日的增量資料為-1.
這個是可能出現負數的.
還有新需求,
下面的SQL模擬不同的使用者簽到了不同的天數
新的需求是查詢簽到天數相同的使用者數量.
比如,都是簽到了一天的使用者數量
我這邊的資料是,
簽到了3天的使用者有兩人,
簽到了4天的使用者有四人,
簽到了5天的使用者有四人..
需求就是統計這個,根據這個數量準備獎品,順便看一下使用者的參與熱情.
採用了兩次分組的方法.
實際的需求,還稍微複雜一些,不過都是上面幾個方法的排列組合.
1.使用數字輔助表填充資料
2.使用外連線求差值資料.
3.使用union all 拼接行轉列的資料
4.使用兩次group by求達到相同條件的彙總資料.
行轉列參考:
http://blog.itpub.net/29254281/viewspace-775660/
其中一個活動要求使用者每天簽到,連續若干天,有不同級別的獎勵.
簽到表模擬如下,userid記錄使用者的ID,createtime模擬使用者簽到的時間.
其中nums是數字輔助表,用法參見
http://blog.itpub.net/29254281/viewspace-1362897/
-
create table award_chance_history
-
(
-
id int primary key auto_increment,
-
userid int,
-
createtime datetime
-
);
-
-
insert into award_chance_history(userid,createtime)
- select ceil(rand()*10000),str_to_date('2014-12-15','%Y-%m-%d')+interval ceil(rand()*10000) minute from nums where id<30;
上面的SQL模擬了一批使用者的簽到資料.
程式研發都已經做完了,需求拿了一個excel模板,讓我統計每天的每小時使用者簽到情況.
這個應該是行轉列的一個典型應用吧
-
select
-
h,
-
sum(case when createtime='2014-12-15' then c else 0 end) 15簽到,
-
sum(case when createtime='2014-12-16' then c else 0 end) 16簽到,
-
sum(case when createtime='2014-12-17' then c else 0 end) 17簽到,
-
sum(case when createtime='2014-12-18' then c else 0 end) 18簽到,
-
sum(case when createtime='2014-12-19' then c else 0 end) 19簽到,
-
sum(case when createtime='2014-12-20' then c else 0 end) 20簽到,
-
sum(case when createtime='2014-12-21' then c else 0 end) 21簽到
-
from
-
(
-
select
-
date_format(createtime,'%Y-%m-%d') createtime,
-
hour(createtime) h,
-
count(*) c
-
from award_chance_history
-
group by
-
date_format(createtime,'%Y-%m-%d'),
-
hour(createtime)
-
) a
- group by h with rollup;
一會兒需求又來了,說是中間缺資料啊.沒有18點,21點的資料啊.
我解釋了半天,說是那幾個時間點,沒有使用者簽到.
人家需求不管,說是沒有使用者簽到的時間段,可以補成0.
(最近天天加班,心情不好,當時真想掐死她..)
不過其實也不難.使用數字輔助表就可以了.
-
select
-
h 小時,
-
sum(case when createtime='2014-12-15' then c else 0 end) 15簽到,
-
sum(case when createtime='2014-12-16' then c else 0 end) 16簽到,
-
sum(case when createtime='2014-12-17' then c else 0 end) 17簽到,
-
sum(case when createtime='2014-12-18' then c else 0 end) 18簽到,
-
sum(case when createtime='2014-12-19' then c else 0 end) 19簽到,
-
sum(case when createtime='2014-12-20' then c else 0 end) 20簽到,
-
sum(case when createtime='2014-12-21' then c else 0 end) 21簽到
-
from
-
(
-
select b.h h,c.createtime,c.c from
-
(
-
select id-1 h from nums where id<=24
-
) b
-
left join
-
(
-
select
-
date_format(createtime,'%Y-%m-%d') createtime,
-
hour(createtime) h,
-
count(*) c
-
from award_chance_history
-
group by
-
date_format(createtime,'%Y-%m-%d'),
-
hour(createtime)
-
) c on (b.h=c.h)
-
) a
- group by h with rollup;
好了,沒有使用者簽到的時間段也填充了0
剛做完,新需求又來了,“統計每天的使用者簽到資料和每天的增量資料”..好吧
透過左連線,求得兩天內的簽到差值,然後union當天的簽到資料,最後再行轉列.
他的增量資料是這個意思,比如16日4人簽到,17日5人簽到,那麼17日的增量資料為1.
當然,如果15日的簽到人數為5,16日的簽到人數為4,那麼16日的增量資料為-1.
這個是可能出現負數的.
-
select
-
type 型別,
-
sum(case when createtime='2014-12-15' then c else 0 end) 15簽到,
-
sum(case when createtime='2014-12-16' then c else 0 end) 16簽到,
-
sum(case when createtime='2014-12-17' then c else 0 end) 17簽到,
-
sum(case when createtime='2014-12-18' then c else 0 end) 18簽到,
-
sum(case when createtime='2014-12-19' then c else 0 end) 19簽到,
-
sum(case when createtime='2014-12-20' then c else 0 end) 20簽到,
-
sum(case when createtime='2014-12-21' then c else 0 end) 21簽到
-
from
-
(
-
select b.createtime,ifnull(b.c-c.c,0) c,'增量' type from
-
(
-
select
-
date_format(createtime,'%Y-%m-%d') createtime,
-
count(*) c
-
from award_chance_history
-
group by
-
date_format(createtime,'%Y-%m-%d')
-
) b
-
left join
-
(
-
select
-
date_format(createtime,'%Y-%m-%d') createtime,
-
count(*) c
-
from award_chance_history
-
group by
-
date_format(createtime,'%Y-%m-%d')
-
) c on(b.createtime=c.createtime+ interval 1 day)
-
union all
-
select
-
date_format(createtime,'%Y-%m-%d') createtime,
-
count(*) c,
-
'當前'
-
from award_chance_history
-
group by
-
date_format(createtime,'%Y-%m-%d')
-
) a
- group by type
- order by case when type='當前' then 1 else 0 end desc;
還有新需求,
下面的SQL模擬不同的使用者簽到了不同的天數
-
insert into award_chance_history(userid,createtime)
-
select userid,createtime + interval ceil(rand()*10) day from award_chance_history,nums
- where nums.id <10 order by rand() limit 150;
比如,都是簽到了一天的使用者數量
我這邊的資料是,
簽到了3天的使用者有兩人,
簽到了4天的使用者有四人,
簽到了5天的使用者有四人..
需求就是統計這個,根據這個數量準備獎品,順便看一下使用者的參與熱情.
採用了兩次分組的方法.
-
select
-
sum(case when day=1 then cn else 0 end) 1天,
-
sum(case when day=2 then cn else 0 end) 2天,
-
sum(case when day=3 then cn else 0 end) 3天,
-
sum(case when day=4 then cn else 0 end) 4天,
-
sum(case when day=5 then cn else 0 end) 5天,
-
sum(case when day=6 then cn else 0 end) 6天,
-
sum(case when day=7 then cn else 0 end) 7天,
-
sum(case when day=8 then cn else 0 end) 8天,
-
sum(case when day=9 then cn else 0 end) 9天,
-
sum(case when day=10 then cn else 0 end) 10天
-
from
-
(
-
select c day,count(*) cn
-
from
-
(
-
select userid,count(*) c from award_chance_history group by userid
-
) a
-
group by c
- ) b
實際的需求,還稍微複雜一些,不過都是上面幾個方法的排列組合.
1.使用數字輔助表填充資料
2.使用外連線求差值資料.
3.使用union all 拼接行轉列的資料
4.使用兩次group by求達到相同條件的彙總資料.
行轉列參考:
http://blog.itpub.net/29254281/viewspace-775660/
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29734436/viewspace-1380010/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 一個行轉列的應用
- SQL 行轉列,列轉行SQL
- Mysql - 行轉列、列轉行MySql
- oracle 11g的行轉列、列轉行Oracle
- sql的行轉列(PIVOT)與列轉行(UNPIVOT)SQL
- Oracle行轉列、列轉行的Sql語句總結OracleSQL
- 汽車行業的CRM應用(下) (轉)行業
- 汽車行業的CRM應用(中) (轉)行業
- hive經典案列--top N(行轉列\列轉行)Hive
- rownum偽列的應用
- SQL列轉行SQL
- mysql列轉行MySql
- oracle 列轉行Oracle
- postgresql 列轉行SQL
- mysql 行轉列MySql
- oracle列轉行Oracle
- Java執行緒的討論與應用(轉)Java執行緒
- UltraEdit 列操作及列轉行
- Oracle行轉列的函式Oracle函式
- oracle行列轉換-行轉列Oracle
- oracle行列轉換-列轉行Oracle
- 動態行轉列
- SQL 列行轉換SQL
- DB2行列轉置之行轉列DB2
- Oracle 行轉列的sql語句OracleSQL
- 用XML/XSLT將行資料轉換為列資料 (轉)XML
- RAID 磁碟陣列的應用AI陣列
- 動態record陣列的應用陣列
- 只需設定分隔符,完全自適應行轉列~~
- php陣列轉換js陣列操作及json_encode應用PHP陣列JSON
- ERP在汽車製造行業中的應用(轉)行業
- 開發具有Windows工作列佈告區圖示的應用程式 (轉)Windows
- 用listagg函式分組實現列轉行函式
- oracle中多列轉行Oracle
- Hive行轉列函式Hive函式
- 動態固定行轉列
- mysql基礎 行轉列MySql
- Kettle實現行轉列