SQL Server 中的 Pivot 語法

從 SQL Server 2005 起, 支援了 Pivot 語法及 UnPivot 語法.

利用 Pivot 語法, 可以做出一些轉置及特殊報表使用的查詢結果(對於要分析資料時特別有用).

先來建立範例資料, 這個資料表是一個流水號(logid, 一個會員編號 userno, 一個投票標的號 voteid, 一個時間欄位 createtime), 為能將資料表模擬真實的狀況, 建立一些資料來供應用, script 如下:


CREATE TABLE VOTELOG (logid int identity(1,1), userno int, voteid int, createtime datetime default getdate())
insert into VOTELOG (userno, voteid, createtime) values (1, 1, '2010/7/1 1:15')
insert into VOTELOG (userno, voteid, createtime) values (2, 1, '2010/7/1 3:27')
insert into VOTELOG (userno, voteid, createtime) values (4, 2, '2010/7/1 3:29')
insert into VOTELOG (userno, voteid, createtime) values (15, 2, '2010/7/1 16:31')
insert into VOTELOG (userno, voteid, createtime) values (35, 1, '2010/7/1 17:31')
insert into VOTELOG (userno, voteid, createtime) values (24, 1, '2010/7/1 17:38')
insert into VOTELOG (userno, voteid, createtime) values (8, 2, '2010/7/1 20:18')
insert into VOTELOG (userno, voteid, createtime) values (7, 2, '2010/7/2 2:22')
insert into VOTELOG (userno, voteid, createtime) values (32, 1, '2010/7/2 2:36')
insert into VOTELOG (userno, voteid, createtime) values (9, 1, '2010/7/2 10:09')
insert into VOTELOG (userno, voteid, createtime) values (25, 2, '2010/7/2 13:35')
insert into VOTELOG (userno, voteid, createtime) values (19, 2, '2010/7/2 18:19')
insert into VOTELOG (userno, voteid, createtime) values (16, 2, '2010/7/2 19:28')
insert into VOTELOG (userno, voteid, createtime) values (6, 1, '2010/7/2 23:06')
insert into VOTELOG (userno, voteid, createtime) values (36, 2, '2010/7/3 0:42')
insert into VOTELOG (userno, voteid, createtime) values (18, 2, '2010/7/3 2:19')

假如現在我們需要分時的每日投票狀況的報表, 可以使用如下的 pivot查詢:


select dates, [0],[1],[2],[3],[4],[5],[6],[7], [8],[9],[10],[11],[12],[13],[14],[15], [16],[17],[18],[19],[20],[21],[22],[23]
from (select convert(varchar, createtime, 111) as dates, datepart(hh, createtime) as hours from votelog ) as cum
pivot (count(hours) for hours in ( [0],[1],[2],[3],[4],[5],[6],[7], [8],[9],[10],[11],[12],[13],[14],[15], [16],[17],[18],[19],[20],[21],[22],[23] )) as pv

查詢結果如下:

這樣可以很清楚地呈現出, 每日分時的統計狀況, 當然, 若是要查的是分開兩個候選人的結果, 僅需要在中間的子查詢(cum)的裡面多加入 where 條件即可.

另外多提一個部分, 這樣的查詢, 可以在子查詢先做集總, 再進行 pivot, 效果會更好(尤其在資料量愈大時), 語法如下:


select dates, [0],[1],[2],[3],[4],[5],[6],[7], [8],[9],[10],[11],[12],[13],[14],[15], [16],[17],[18],[19],[20],[21],[22],[23]
from (select convert(varchar, createtime, 111) as dates, datepart(hh, createtime) as hours, count(*) as counts from votelog group by convert(varchar, createtime, 111), datepart(hh, createtime) ) as cum
pivot (count(counts) for hours in ( [0],[1],[2],[3],[4],[5],[6],[7], [8],[9],[10],[11],[12],[13],[14],[15], [16],[17],[18],[19],[20],[21],[22],[23] )) as pv

也就是在子查詢中(cum), 先 group 好, 再進行 pivot 的查詢(但記得要用sum前面count結果), 這樣的效果會更有效率.

pivot 及 unpivot 語法可以參考以下資料:

使用 PIVOT 和 UNPIVOT: http://technet.microsoft.com/zh-tw/library/ms177410%28SQL.90%29.aspx

另外有人整理好的 cross-table stored procedure也很方便, 可以參考這篇: http://www.sqlteam.com/article/dynamic-cross-tabs-pivot-tables

主動發佈給搜尋引擎的wordpress plugin PuSHPress

從高登那裡看來看: http://gordon168.tw/?p=368

很有意思的 plugin, 可以主動發行內容到 google 搜尋引擎, 比從搜尋引擎來抓的速度會快很多. 達成發行文章後, 馬上發佈到各 subscriber 及搜尋引擎資料庫.

這個 PubSubHubBub 很有趣的地方在於是 google 支持的一項新 protocol, 用來把內容發佈出來的資料, 主動對 hub 發行, 並主動通知 subscriber, 可以達到更有效的發行.

不過這種東西的下場, 很有可能被濫用或一些廣告, 所以…..

不過也不用想太多, 基本上就是用就對了.

PubSubHubBub 的專案連結: http://code.google.com/p/pubsubhubbub/

plugin連結: http://wordpress.org/extend/plugins/pushpress/

這裡有個介紹 What is PubSubHubbub? 的影片, 可以參考: http://www.youtube.com/watch?v=B5kHx0rGkec

SQL Server中的索引離散狀況

SQL Server 資料庫中的索引是用來加速查詢效率的一種方式, 利用了空間換取時間的方法來將查詢的速度增加.

既然是利用空間換取時間的方法, 代表著該存放的空間, 資料的排列狀況就會隨著時間的過去, 有資料的新增, 刪除, 修改時, 造成的索引離散狀況, 若是索引離散時, 代表著存取這些索引的 IO 量會增加, 也代表著效率會下降的狀況會發生.

如何查詢這個資料, 可以參考這篇文章: http://sharedderrick.blogspot.com/2010/02/index-fragmentation.html 有詳細的說明, 利用該查詢指令, 若是要查找特定 table 的話, 可以這樣下(SQL Server 2005以上版本):

SELECT sch.name N’結構描述’, obj.name N’資料表’,
inx.name AS N’索引名稱’,
index_type_desc N’索引類型’,
avg_fragmentation_in_percent ‘片段(%)’,
avg_page_space_used_in_percent N’頁面飽和度(%)’,
fragment_count,
avg_fragment_size_in_pages,
page_count
FROM sys.dm_db_index_physical_stats (DB_ID(), OBJECT_ID(‘TABLE_NAME’),NULL, NULL, ‘SAMPLED’) AS phy
INNER JOIN sys.indexes AS inx ON phy.object_id = inx.object_id AND phy.index_id = inx.index_id
INNER JOIN sys.objects AS obj ON phy.object_id = obj.object_id
INNER JOIN sys.schemas AS sch ON obj.schema_id = sch.schema_id
WHERE index_type_desc <> ‘HEAP’  AND fragment_count IS NOT NULL AND avg_fragment_size_in_pages IS NOT NULL
ORDER BY 5 DESC

利用了 OBJECT_ID() 函數, 把 table 的 object id 找出來, 便能指定查找特定 table 中的索引離散狀況.

根據微軟官方的資料: http://technet.microsoft.com/zh-tw/library/ms189858.aspx , 離散狀況在 5% 以下不需要調整, 在 5% ~ 30%之間, 可以利用 ALTER INDEX REORGNIZE 來進行重組, 而大於 30% 時, 可以使用 ALTER INDEX REBUILD (ONLINE = ON) 來進行索引重建.

不過若系統效能允許的狀況下, 其實也是可以直接使用 DROP INDEX, CREATE INDEX 的方式來重建的.

其他相關文章一併整理如下:

Microsoft SQL Server 2000 Index Defragmentation Best Practices
http://technet.microsoft.com/en-us/library/cc966523.aspx

sys.dm_db_index_physical_stats (Transact-SQL)
http://technet.microsoft.com/zh-tw/library/ms188917.aspx

ALTER INDEX (Transact-SQL)
http://msdn.microsoft.com/en-us/library/ms188388.aspx

Table and Index size in SQL Server
http://stackoverflow.com/questions/316831/table-and-index-size-in-sql-server

SQL Server Indexes
http://odetocode.com/articles/70.aspx

升級到2.9.1.1版本/正體中文官網上線

今天將 wordpress mu 升級到 2.9.1.1 版本, 但原來是 2.8.2 的版本, 所以需要經過這個步驟 (http://ocaoimh.ie/wordpress-mu-2-8-3/), 先升級到 2.8.3, 否則在使用自動升級會中止無法順利自動升級版本. (使用手動升級的就不會有這個問題)

升級完成後, 也順便找一下繁體中文的語言檔, 發現一件很開心的事, 就是 wordpress 有正式的官方網站囉, 而且這樣一來, 繁體中文的更新速度就會快更多了呢! 官網在此: http://tw.wordpress.org/ , 而新的語系檔可以到該 svn 下載, http://svn.automattic.com/wordpress-i18n/zh_TW/trunk/messages/zh_TW.mo, 放到 wordpress mu 的目錄: /wp-includes/languages 中即可, 這樣升級含中文方便多了.

真方便!

Broken Link Checker-WordPress Plugin

在寫網頁時, 有時要去檢查自己網站內的連結是否還是可用的, 通常需要一些小工具或外部服務來幫忙, 不過在 wordpress 中, 有個貼心的小插件(plugin), Broken Link Checker, 可供使用.

安裝之後, 會在[工具]中多一項 Broken Links 的功能選項, 而且會自動進行網誌內的連結檢查(包含內部及外部的), 十分方便好用, 不再需要一個一個檢查或是找其他的外部工具來檢查, 因為這個 plugin 會將網誌內的 link 逐一檢查, 不但有效率, 也很快速.

t-bl

官方的連結在這裡: http://wordpress.org/extend/plugins/broken-link-checker/ 大家可以用看看囉!

SQL Server全文檢索資料庫的復原

一般資料庫我們備份後, 由於全文檢索技術, 和資料庫引擎不同, 是使用檔案及全文檢索引擎架構的一種方式, 所以在回復到異地後, 資料庫上線了, 但 fulltext catalog 內的資全文檢索資料不能用的問題, 這時候, 只需要再做一次 rebuild 即可, 因為所有的資料庫及相關欄位等設定其實都在, 但路徑上及檔案結構上的問題, 導致會有無法讀取的狀況. 這時候, 於 restore 資料庫後, 做一次 fulltext catalog 的 rebuild, 問題就能順利解決了.

若是原地復原, 則沒有這個問題.

二的補數來表現負數

這是一個二進位的小問題. 在電腦的世界裡, 使用二進位表示法來存放數字是再單純不過的. 不過數字為能有更佳的效率, 有一些設計是很重要的, 例如用二的補數來表示負數, 以下為一個例子.

假設用一個 byte 來代表數字的話, 則共有8個bit可用, 最高字元保留給符號, 而數字就用二進位法來放, 所以8個bit表示如下:

7-6-5-4-3-2-1-0

其中第0個bit最右側, 也就是最低位元, 最左邊是第7個bit, 也就是最高位元.

接下來要說明數字囉

00000001 (b)=1(d)

00000010(b)=2(d)

00000100(b)=4(d)

00010101(b)=21(d)

…. 以此類推, 而最大正數可以用這個表示, 除了第7個bit不動, 其餘都是1的話:

01111111(b)=127(d)

好, 接下來看負數怎麼表示. 先來看所謂二的補數, 二的補數(two’s complement)就是將位元反置後再加一, 來看一個例子:

25(d)=00011001(b)

而要代表-25的二進位數, 則用 00011001(b)反置後再加一

1. 反置 11100110

2. 再加1 得 11100111,

3. 所以得 11100111(b)=-25(d)

再舉一個例子, 2(d)=00000010(b),

1. 反置 11111101,

2. 再加1得 11111110,

3. 所以得11111110(b)=-2(d)

接下來看如何反過來做, 若今天有個值是 110001010(b) 怎麼算回來呢?

1. 先減1, 110001001

2. 再反置得 001110110

3. 所以得 001110110(b)=118(d)

4. 所以 110001010(b)=-118(d)

這樣就行囉!

所以 8個bit的範圍最小到最大就是 -128~127共256個數字.

參考資料:

http://blog.udn.com/Piner/3033066

http://squall.cs.ntou.edu.tw/cprog/Materials/TwosComplementFormat.html

wordpress中好看的字型

在 wordpress 中, 預設的字型(英數)是 Georgia, 這個字型還蠻好看的, 所以在 wordpress 內寫英文字句都令人很賞心閱目, 而今天又發現另一個字型也有這樣的特性, 是 Constantia. 這兩種字型的特性, 就是英數時, 會高高低低的, 有一種硬硬的打字機的感覺. 這樣將在 word 中使用該兩種字體的圖擷下來供參考:

good-font

post revision功能真是不錯

原來在版本 2.6 時已經有了一個很特別的新功能, 稱之前 post revisions, 也就是文章版本管理(控制), 這個功能還蠻強大好用的, 一方面像是時光還原器, 一方面還能做版本比對, 的確是對於寫長篇大論的文章有非常方便之處, 而且其實有時若是沒有存到檔, 配合的 auto save 功能也能發揮作用, 讓損失降到最低.

預設功能在發表文章頁面上, 有個”文章版本”, 這個區塊, 如下:

post-revisions

點擊進去後, 就可以看到一個很友善的版本選擇及管理功能, 如下:

post-revisions2

然後可以挑選要比較的版本, 並按下[比較不同版本]後, 就可以列出兩個比較, 如下:

post-revisions3

如此一來, 便能一目了然, 方便文章的撰寫, (真的是在寫文章編輯的好工具), 這樣的計設, 功能真的很強大.

當然, 有這個功能, 也會需要一些空間來存放, 若是覺得會浪費空間或是要刪除這個備份, 當然也有可以取消地方, 可以參考: http://blog.dogg3h.com/how-to-disable-wordpress-post-revision

原來我現在才發現這個功能, 真的 lag 很久耶.