2012年8月29日 星期三

MERGE 命令語法 ( 限 SQL 2008 以上使用 )


試了好幾次,寫好的 MERGE 命令語法完~~~~全不能用。
去爬文後,看到的答案,大多都是說「不支援SQL 2005」。
 
既然 MERGE 這個命令語法,不支援SQL 2005
就記錄一下,以備日後可以參考。


/* MERGE 命令語法 */
 MERGE M目標_產品資料 AS T
 USING M來源_產品資料 AS S
    ON T.產品編號= S.產品編號
  /* 當目標資料表與來源資料表條件吻合時,執行下面動作。*/
  WHEN MATCHED
  THEN UPDATE
          SET T.產品名稱=S.產品名稱, T.單價=S.單價
  /* 當目標資料表(T)中不存,來源資料表(S)中有的產品編號時,執行下面動作。*/
  WHEN NOT MATCHED BY TARGET
  THEN INSERT (產品編號, 產品名稱, 單價,)
       VALUES (S.產品編號, S.產品名稱, S.單價, 0)
  /* 當目標資料表(T)中存在,來源資料表(S)不存在此產品編號時,執行下面動作。*/
  WHEN NOT MATCHED BY SOURCE
  THEN DELETE
; /* 一定要加分號做結尾,否則會出錯。 */


雖然還沒機會可以使用,但MERGE看起來就是可以一次比對完兩個資料表中的差異,並且將來源資料表(SOURCE)中的結果,異動到目標資料表(TARGET),完成UPDATEINSERTDELETE等動作。




2012年8月28日 星期二

合併複數資料表的方式


/* 合併資料表*/

合併兩張資料表的方式,大概有下面三種。

--(1)用逗點分隔
select * from score,personal

--(2)使用INNER JOIN
select * from score INNER JOIN personal

--(3)省略INNER,只使用JOIN
select * from score JOIN personal


下面三個語法,有的只有 JOIN 條件,有的只有 WHERE 條件,但結果都是一樣。

--(1)

--下面的語法,把INNER JOIN 中 ON 的條件挪到 where 裡了。
select *
  from score S,personal P
 where S.std_num=P.std_num and p.addr like '__'

--(2)
select *
  from score S join personal P
    on S.std_num=P.std_num
 where p.addr like '__'

--(3)
--下面語法沒有使用 where 是可以的,但僅適合簡易的資料查詢。
--「p.addr like '_竹_'」合併到 JOIN 的條件裡了。
select *
  from score S join personal P
    on S.std_num=P.std_num and p.addr like '__'



用逗點來做 INNER JOIN,對我來說,算是蠻新奇的作法。
我以前都不知道可以這樣使用...




2012年8月24日 星期五

使用模糊查詢


/* 模糊查詢*/

在資料表中,取出符合條件的資料的方法很多。
可以在 Where 中使用 Likein,或是使用 LEFTRIGHTSUBSTRING等等的函式。

--例如找出住在新竹縣市的人。
select * from [personal] where left([addr],2)='新竹'
select * from [personal] where substring([addr],1,2)='新竹'
select * from [personal] where [addr] like '新竹%'
select * from [personal] where [addr] in ('新竹市','新竹縣')

--底線'_'是指任何字元,雖然可以模糊查詢,但會受到字元長度限制。
--一個底線代表一個字元。
select * from [personal] where [addr] like '新竹_'
select * from [personal] where [addr] like '__'

--使用中括弧也是模糊查詢的一種。
select * from [personal] where [addr] like '新竹[縣市]'

--另外老師有教[^]
--這個「^」到底是什麼意思?下次上課要問清楚。
select * from [personal] where [addr] like '[^][縣市]'




擷取欄位中的部分字串


/* 截取字串*/

--LEFT( character_expression , integer_expression )
--LEFT( [字串], [數字(要擷取的長度)] )
SELECT LEFT(std_name,1) FROM SCORE

--RIGHT( character_expression , integer_expression )
--RIGHT( [字串], [數字(要擷取的長度)] )
SELECT RIGHT(std_name,1) FROM SCORE

--SUBSTRING( expression ,start , length )
--SUBSTRING( [字串], [數字(取值的起始位置)] , [數字(要擷取的長度)] )
select substring(std_name,1,1) 姓氏from score
select substring(std_name,2,10) 名字from score


substringVB用好久了,我竟然不知道在SQL裡面也有一樣的函式可以用。
我太孤陋寡聞了...




2012年8月23日 星期四

使用 TOP 篩選資料


/* TOP N PERCENT WITH TIES */
在工作上,使用到 TOP 的機會,不能算多,但還是會有用到。
但 TOP N PERCENT 就真的很少很少使用。
所以昨天上課時,要做老師出的題目。
在這邊做個紀錄,以後要用的話也比較好找。


-- TOP N 可以依照排序條件,取出前N筆資料。
SELECT TOP 5 *, co+db+sp+td 總分from score order by 總分


-- TOP N PERCENT 可以取出前N% 的資料。
SELECT TOP 5 PERCENT *, co+db+sp+td 總分from score order by 總分


-- TOP 5 WITH TIES 可以取符合前五名的資料(包含同分數的)
-- 舉例,假設前五名中,有個第五名同分,若只使用TOP 5 僅會取出筆資料。
-- 使用TOP 5 WITH TIES 則會取出筆資料。
SELECT TOP 5 WITH TIES *, co+db+sp+td 總分from score order by 總分


-- TOP 5 PERCENT WITH TIES 可以取符合前5% 的資料(包含同分數的)
SELECT TOP 5 PERCENT WITH TIES *, co+db+sp+td 總分from score order by 總分



欄位取別名的方式



/* 取別名的方式 */
1.使用 AS
2.使用 =
3.省略 AS


/* 參考:*/
SELECT std_num as 學生名稱 FROM personal
SELECT 學生名稱=std_num    FROM personal
SELECT std_num 學生名稱    FROM personal (這個方式我很少用...)

閱讀 SQL の MSDN 的參考


每次在看SQL的MSDN,常常都會一頭霧水。沒辦法,我是英文苦手。
最近看《SQL語法範例辭典》,看到〈關於本書的一些注意事項〉時,有種挖到寶的感覺。

以往看MSDN,大概會看到像下列這樣的東西。

SELECT [ ALL | DISTINCT ]
    [TOP expression [PERCENT] [ WITH TIES ] ]
    < select_list >
    [ INTO new_table ]
    [ FROM { <table_source> } [ ,...n ] ]
    [ WHERE <search_condition> ]
    [ GROUP BY [ ALL ] group_by_expression [ ,...n ]
                [ WITH { CUBE | ROLLUP } ]
    ]
    [ HAVING < search_condition > ]

有一大堆的中括弧、大括弧,還有一大堆的英文字。
明明就是很常使用的 SELECT、FROM、WHERE、GROUP BY、HAVING、ORDER BY,但在 MSDN 上就是看得霧沙沙。

但在〈關於本書的一些注意事項〉中,有下面這樣的說明,稍微對照參數跟備註的部分,就容易閱讀的多了。
 
/* 語法 */
SELECT [ALL | DISTINCT ] expression [, expression ... ]
  FROM table_name [, table_name ... ]
[WHERE where_expression]
[GROUP BY expression [, expression ... ][HAVING where_expression ]]
[ORDER BY expression [, expression ... ]]

/* 參數 */
table_name        要選擇其中列資料的資料表名稱
expression        任意陳述式
where_expression  進一步篩選資料用的條件式

備註:
SELECT       保留字
table_name   任意名稱
column       任意名稱,但必須為欄位名稱
statement    SQL 的命令
expression   任意陳述式
[]           表示可以省略
()           這個括弧一定要寫
...          可以不斷重複
A|B          可選擇A B 其中一者
{A|B}        可選擇A B 其中一者,不用寫外側的大括弧

2012年8月22日 星期三

用Char來判斷字元是英文字母或數字

為了改良「判斷身分證字號及統一編號是否正確」,因此在檢查是否符合規則之前,先排除英文字母跟數字之外的其他文字。所以使用Char.IsNumberChar.IsLetter來判斷。


範例:
'檢查滿10碼的身分證字號
If x.Length = 10 then
    '檢查第一碼是否為英文字母
    If Not Char.IsLetter(x.Substring(0, 1)) Then 
        Return "第一碼應為英文字母。"
    End If

    '檢查其餘九碼是否為數字
    For i As Integer = 1 To x.Length - 1
        If Not Char.IsNumber(x.Substring(i, 1)) Then 
            Return "【所得人統一編(證)號】錯誤。"
        End If
    Next
End If


下面是其他的Char的公用方法:

IsControl       指示指定的 Unicode 字元是否分類為控制字元。 
IsDigit         指示 Unicode 字元是否分類為十進位數字。 
IsHighSurrogate 指出指定的 Char 物件是否為高 Surrogate。 
IsLetter        指示 Unicode 字元是否分類為字母。 
IsLetterOrDigit 指示 Unicode 字元是否分類為依字母順序排列的字母或十進位數字。 
IsLower         指示 Unicode 字元是否分類為小寫字母。 
IsLowSurrogate  指出指定的 Char 物件是否為低 Surrogate。 
IsNumber        指示 Unicode 字元是否分類為數字。 
IsPunctuation   指示 Unicode 字元是否分類為標點符號。 
IsSeparator     指示 Unicode 字元是否分類為分隔符號字元。 
IsSurrogate     指示 Unicode 字元是否分類為 Surrogate 字元。 
IsSurrogatePair 指出兩個指定的 Char 物件是否會組成 Surrogate 字組。 
IsSymbol        指示 Unicode 字元是否被分類為符號字元。 
IsUpper         指示 Unicode 字元是否分類為大寫字母。 
IsWhiteSpace    指示 Unicode 字元是否分類為泛空白字元 (White Space)。