乙個略微複雜的Sql行轉列例項

2021-07-26 08:37:03 字數 2996 閱讀 5186

表結構如上,roomid為房間號,ispresent為1表示該房間有人,ispresent為0表示該房間沒人。現在需要統計每個房間以1開始、以0結束的時間,如果有連續的1則取第乙個1建立時間為開始時間,如果有連續的0則取最後乙個0建立時間為結束時間。

先根據roomid和createtime排序,使每個房間每次開房的開始時間和結束時間連在一起,由於資料表中的自增主鍵不一定連續,所以新增一列連續的編號用來判斷是否存在連續的1或連續的0的情況。

select *,row_number()over(order

by roomid,createtime)px into #tem_px from disorderedliverecord

臨時表#tem_px中的資訊如下:

如果有連續的1則取第乙個1建立時間為開始時間,所以要刪除連續的1中除第一條外的其他記錄;

如果有連續的0則取最後乙個0建立時間為結束時間,所以要刪除連續的0中除最後一條外的其他記錄;

最終資料表中只剩下每個房間每次開房唯一的開始時間和結束時間。

查詢連續的1中除第一條外其他記錄的id:

a.px=b.px+1 and a.ispresent=b.ispresent 說明存在連續的ispresent值相同的情況;

a.px=b.px+1 and a.ispresent=b.ispresent and a.ispresent=1 說明存在連續的ispresent值相同且值為1的情況;

因為a.px=b.px+1,所以a.px較大,因此a.id指的是兩條ispresent值相同的記錄中位置靠後那條;

b.id指的是兩條ispresent值相同的記錄中位置靠前的那條。

select a.id from #tem_px a 

inner join #tem_px b on a.px=b.px+1

anda.ispresent=b.ispresent and

a.ispresent=1

anda.roomid=b.roomid

查詢連續的0中除最後一條外其他記錄的id:

a.px=b.px+1 and a.ispresent=b.ispresent 說明存在連續的ispresent值相同的情況;

a.px=b.px+1 and a.ispresent=b.ispresent and a.ispresent=0 說明存在連續的ispresent值相同且值為0的情況;

select b.id from #tem_px a 

inner

join #tem_px b on a.px=b.px+1

and a.ispresent=b.ispresent and a.ispresent=0

and a.roomid=b.roomid

根據需求刪除ispresent值相同的多餘資料。

delete

from #tem_px where id in

(select a.id from #tem_px a

inner

join #tem_px b on a.px=b.px+1

and a.ispresent=b.ispresent and a.ispresent=1

and a.roomid=b.roomid)

delete

from #tem_px where id in

(select b.id from #tem_px a

inner

join #tem_px b on a.px=b.px+1

and a.ispresent=b.ispresent and a.ispresent=0

and a.roomid=b.roomid)

刪除多餘資料後,臨時表#tem_px中的資訊如下:

此時大家發現px列已經不連續了,所以我們需要再新增一列連續的編號用來實現結束時間列轉行。

select

*,row_number()over(order

by roomid,createtime)px2 into

#tem_px2 from #tem_px

臨時表#tem_px2中的資訊如下:

把ispresent=0的結束時間作為乙個新列,放到對應的ispresent=1的開始時間之後。

注意:臨時錶用完之後一定要刪除。

select a.roomid,a.createtime as starttime,b.createtime as endtime from #tem_px2 a

left

join #tem_px2 b on a.px2=b.px2 - 1

and b.ispresent=0

where a.ispresent=1

drop

table #tem_px

drop

table #tem_px2

所得結果如下:

在對sqlserver資料庫表進行複雜地處理時,最重要的是要知道自己的需求是什麼,以及達到這個需求需要經過哪些步驟,然後按照這些步驟寫對應的sql語句,就自然而然地得到了自己想要的結果。

乙個行轉列的應用

liangck小梁 於2008 10 15 生成測試資料 t if object id tempdb.dbo.t is not null drop table t create table t id int,姓名 varchar 4 類別 varchar 1 單位 varchar 6 insert ...

乙個複雜的sql

select f.course node info id as nodeid,c.course node name as nodename,c.course node type as nodelevel,c.course code,case when select course node info ...

記一次複雜sql寫法 ,mysql 動態行轉列

需求 將t program 的豎行,轉向成橫行,在t result 裡面展示出來 直接上sql set sql null select group concat distinct concat max if r.program id p.id,r.value,0 as p.name,into sql...