iamlaosong文
Excel中使用SQL的主要目的是連接數(shù)據(jù)庫(或Excel工作表)導入數(shù)據(jù)或者對這些數(shù)據(jù)進行統(tǒng)計匯總,要達到這個目的,需要好好學習SQL語句的使用。本文主要說明在Excel中如何使用SQL,至于SQL語句本身就不多作介紹了。
數(shù)據(jù)選項卡—現(xiàn)有連接—瀏覽更多 或者 按快捷鍵Alt+D+D+D
選擇要查詢的Excel文件和文件中的的工作表,就可以將相應工作表的數(shù)據(jù)取過來。表現(xiàn)形式可以是表,也可以是數(shù)據(jù)透視表等。
如果是挑選部分列數(shù)據(jù),就需要用SQL語句(取所有數(shù)據(jù)也可以用SQL語句)。
Select 字段列表 from [工作表名$]
--其中字段列表就是需要選擇的字段,數(shù)據(jù)源用工作表名稱加“$“再用中括號括起來,例如:
select prov_name, city_name, xs_mc, xs_code from [Sheet1$]
select * from [Sheet1$] -- 取所有數(shù)據(jù)
select [no],prov_name,city_name, xs_mc, xs_code from [Sheet1$]
字段名中含有特殊字符的也要用中括號括起來,如/ ?空格 等
Excel查詢沒有偽表概念,對于表達式的計算直接用select既可,例如
Select 23+45 -- 返回68
Select date() -- 返回當前日期
通過修改SQL語句可以變更所取的數(shù)據(jù),也可以將建立查詢時的簡單SQL語句改成復雜的SQL語句。
select prov_name as 省, city_name as 城市, xs_mc as 縣市, xs_code as 編碼 from [Sheet1$]
需要在工作表名稱后面指定數(shù)據(jù)范圍,例如:
select prov_name, city_name, xs_mc, xs_code from [Sheet1$B2:G2000]
或者,將數(shù)據(jù)塊定義為一個名稱,假設定義為mydata,SQL語句如下:
select prov_name, city_name, xs_mc, xs_code from mydata
注意:使用名稱時沒有$符號,也沒有方括號了。
修改SQL語句后,如顯示格式不是預想的那樣,需要去掉“外部數(shù)據(jù)屬性”中“保留列屬性”前面的勾選。方法:點擊右鍵—彈出菜單—表格—外部數(shù)據(jù)屬性,彈出窗口如下:
Select * from [財務部$] union all Select * from [市場部$]
Union是去重復的,即相同的記錄保留一個(類似distinct),Union all則是直接相加兩個結果,不去重復。
Select “財務部” as 部門,* from [財務部$] union all Select “市場部” as 部門,* from [市場部$]
Select * from [部門$] bm, [員工$] yg where bm.部門編碼=yg.部門編碼
如果數(shù)據(jù)不僅來自不同的工作表,還來自不同的文件,一樣可以用union聯(lián)合,例如:
Select “分公司1” as 公司, “財務部” as 部門, * from [F:\SQL之Excel應用\分公司1.xlsx].[財務部$] union all
Select “分公司1” as 公司, “市場部” as 部門, * from [F:\SQL之Excel應用\分公司1.xlsx].[市場部$] union all
Select “分公司2” as 公司, “財務部” as 部門, * from [F:\SQL之Excel應用\分公司2.xlsx].[財務部$] union all
Select “分公司2” as 公司, “市場部” as 部門, * from [F:\SQL之Excel應用\分公司2.xlsx].[市場部$]
因為SQL中已經(jīng)指定了文件名和表名,所以建立連接時連接誰并不重要,這種情況下,建立連接的時候就連接自己,然后再改寫SQL語句。
所謂子查詢就是將一個查詢結果作為數(shù)據(jù)源放在主查詢語句中,多表連接則是將兩個有關聯(lián)的表通過關鍵字段連接在一起查詢,這都是SQL知識,不再贅述,需要注意的是,不同的數(shù)據(jù)庫系統(tǒng)SQL都有些微小的差別,Excel中的SQL也有其自己的一些特點,關于多表查詢的寫法,見本文附錄。
select * from[Sheet1$] where Email like ‘[h-m]%’ --h-m開頭的電子郵件
select * from[Sheet1$] where xs_code like '%[!1,3,5]' –和not like '%[1,3,5]'效果相同
select * from[Sheet1$] where 戶籍&’-’&工作地 like '%合肥%' --中間加個“-”防止誤差
Distinct 去重復、top n 取前n條記錄
除了聚合函數(shù),還有很多其他函數(shù),這些函數(shù)有的是所有數(shù)據(jù)庫系統(tǒng)都有的,有的是數(shù)據(jù)庫系統(tǒng)特有的。Excel中工作表中使用的函數(shù)基本都能在SQL中使用,例如:
有些函數(shù)用法和工作表中略有不同,如date可以取當前日期,但是不能合成日期,合成日期用dateserial(這個函數(shù)只能在SQL中使用)
交叉查詢產生一個透視表,相當于一個矩形二維表,這是Excel特有的查詢,格式如下:
Transform 聚合函數(shù) select 行標簽 from [數(shù)據(jù)表$] groupby 行標簽 pivot 列標簽,例如:
Transform sum(工資) select 部門名稱 from [員工$] group by 部門名稱 pivot 職務
這個語句產生的結果與數(shù)據(jù)透視表差不多,相當于一個語句產生一個數(shù)據(jù)透視表,當然這個透視表是固定的,和語句對應的。其中的select語句,相當于數(shù)據(jù)透視表的行字段,其中的聚合函數(shù)的參數(shù)相當于拖到數(shù)據(jù)透視表數(shù)據(jù)區(qū)域的值字段,使用的聚合函數(shù)即值字段的匯總方式。其中的 pivot字段相當于數(shù)據(jù)透視表的列字段,后面的IN (value1[, value2[, ...]])],相當列字段中的項的排序和篩選,擺弄過數(shù)據(jù)透視表,將transform/pivot語句與數(shù)據(jù)透視表對照,可以輕松掌握這個MS JET新增SQL語句??匆幌滦Ч?/p>
列標簽篩選
Transform sum(工資) select 部門名稱 from [員工$] group by 部門名稱 pivot 職務 in (‘主管’, ‘經(jīng)理’)
多個行標簽
Transform sum(工資) select職務,性別from [員工$] group by職務,性別pivot 部門名稱
如需要添加總計,則需要先構造一個子查詢結果,這個結果由正常的查詢和統(tǒng)計查詢聯(lián)合在一起,再以這個結果作為數(shù)據(jù)源,構成上面的二維表。例如:
Transform sum(工資) select 部門名稱 from (
Select 部門名稱,職務,工資 from [員工$] union all
Select 部門名稱,’總計’,sum(工資) from [員工$] group by部門名稱
) group by 部門名稱 pivot 職務 in (‘主管’, ‘經(jīng)理,’職員’,’總計’ )
SQL查詢時字段類型是由前8行數(shù)據(jù)決定的(這個數(shù)字是Excel定的),如果前8行都是數(shù)值型,后面有文本型數(shù)字,則查詢結果中這些數(shù)字變成為空;前8行是文本型,后面是數(shù)值型則不影響,似乎查詢結果偏向文本。如果前8行中類型不一致,有數(shù)值型,也有文本型數(shù)字,可以通過在連接字符串中加入IMEX=1則后面有文本型字符也沒關系,但是,如果前8行都是數(shù)值型,加了這個也不管用,因為前8行已經(jīng)決定是數(shù)值型了。加IMEX位置如下:
Provider=Microsoft.ACE.OLEDB.12.0;UserID=Admin;Data Source=C:\Documents and Settings\Administrator\桌面\tb_city_zd.xls;Mode=ShareDeny Write;Extended Properties="HDR=YES;IMEX=1";Jet OLEDB:System database="";JetOLEDB:Registry Path="";Jet OLEDB:Engine Type=35;Jet OLEDB:DatabaseLocking Mode=0;Jet OLEDB:Global Partial Bulk Ops=2;Jet OLEDB:Global BulkTransactions=1;Jet OLEDB:New Database Password="";Jet OLEDB:CreateSystem Database=False;Jet OLEDB:Encrypt Database=False;Jet OLEDB:Don't CopyLocale on Compact=False;Jet OLEDB:Compact Without Replica Repair=False;JetOLEDB:SFP=False;Jet OLEDB:Support Complex Data=False
隨著我們建立的查詢越來越多,打開現(xiàn)有連接時會出現(xiàn)很多我們原來建立的連接,這些連接是Windows自動保存以便于我們再次使用的,如要刪除,可進入“我的文檔”下面的“我的數(shù)據(jù)源”文件夾,刪除這些無用的數(shù)據(jù)源或者直接刪除“我的數(shù)據(jù)源”文件夾。
刪除這些連接不會影響原來建立的那些查詢。
可以利用MQ工具建立查詢,對于不熟悉SQL語言的可以用這個調試SQL語句。MQ向導會提供可視化工具,一步一步引導我們得到所需的數(shù)據(jù)。查詢生成后,可以點擊“SQL”按鈕進一步修改SQL語句。
如果不能選擇xlsx文件,是因為數(shù)據(jù)源版本驅動太低,進入控制面板--管理工具—數(shù)據(jù)源(ODBC),點擊配置,數(shù)據(jù)庫版本選擇Excel 12.0版本(office2007以上);如果找不到12.012.0以上版本,就刪除原來的數(shù)據(jù)源Excel files,重新添加一個,注意要選擇帶有xlsx的驅動程序。
office版本和版本號:office97 : 8.0、office2000 : 9.0、officeXP(2002) : 10.0、office2003 : 11.0、office2007: 12.0、office2010 : 14.0、office2013: 15.0
選擇文件并確定后,如果提示“數(shù)據(jù)源中沒有包含可見的表格”,點擊確定,在隨后彈出的向導窗口中點擊“選項”按鈕,勾選“系統(tǒng)表”,確定后就可以看到表了,如下圖:
Insert into [員工$] (姓名,性別,工資) values (‘宋定才’,’男’,5000)
Provider=Microsoft.ACE.OLEDB.12.0;Password="";UserID=Admin;Data Source=D:\Lc\link.mdb;Mode=Share Deny Write;ExtendedProperties="";Jet OLEDB:System database="";JetOLEDB:Registry Path="";Jet OLEDB:Database Password="";JetOLEDB:Engine Type=5;Jet OLEDB:Database Locking Mode=0;Jet OLEDB:Global PartialBulk Ops=2;Jet OLEDB:Global Bulk Transactions=1;Jet OLEDB:New DatabasePassword="";Jet OLEDB:Create System Database=False;Jet OLEDB:EncryptDatabase=False;Jet OLEDB:Don't Copy Locale on Compact=False;Jet OLEDB:CompactWithout Replica Repair=False;Jet OLEDB:SFP=False;Jet OLEDB:Support ComplexData=False
Dim cnnAs Object, rst As Object
Set cnn =CreateObject("ADODB.Connection")
Set rst =CreateObject("ADODB.Recordset")
其實這種方法更實用,因為加引用必須是熟悉系統(tǒng)的人才能操作,如果將寫好的程序給一般人使用,難道每次你還指導他去加引用?
cnn.Open "Provider=msdaora;DataSource=dl580;User Id=username;Password=userpasswd;"
其中dl580是Oracle客戶端配置的連接名稱,后面是Oracle用戶名和密碼。
嵌套查詢是將一個SELECT語句包含在另一個SELECT語句的WHERE子句中,也稱為子查詢。子查詢(內層查詢)的結果用作建立其父查詢(外層查詢)的條件,因此,子查詢的結果必須有確定的值。利用嵌套查詢可以將幾個簡單查詢組成一個復雜查詢,從而增強SQL的查詢能力。
1、查詢“張三”選修的課程和成績
select 學號,課程,成績 from [課程$] where 學號 = (select 學號 from [學生$] where 姓名 ="張三")
2、查詢“張三”選修的語文課和成績
select 學號,課程,成績 from [課程$] where 學號 = (select 學號 from [學生$] where 姓名 ="張三" and 課程="語文")
3、查詢所有考試學生的成績
select * FROM [課程$] where 成績 not in (select distinct 學號 from [學生$])
合并查詢想必大家都知道了,數(shù)據(jù)透視表多表查詢,一般都使用的是合并查詢,它合并的是兩個或兩個以上查詢的結果。參加合并查詢的列數(shù)要相同,對應列的數(shù)據(jù)類型必須兼容,各語句中對應的結果集列出現(xiàn)的順序必須相同。
與連接查詢相比,聯(lián)合查詢增加記錄的行數(shù),連接查詢則是增加記錄的列數(shù)。聯(lián)合查詢語句如下:
select * from [] union [all]
其中ALL選項保留結果集中的重復記錄,默認時系統(tǒng)自動刪除記錄。如,依據(jù)學號查詢語文和物理成績:
select 學號,成績, 課程 from [課程$] where 課程= "語文" union select 學號, 成績,課程 from [課程$] where 課程= "物理"
多表查詢亦稱連接查詢,它同時涉及兩個或兩個以上的公共字段或語義相同的字段,也就是說數(shù)據(jù)表是通過表的列(字段)來體現(xiàn)的。是數(shù)據(jù)透視表中最重要的的一種查詢。連接操作的目的就是通過加在連接字段的條件將多個表連接在一起,以便在多個表中查詢數(shù)據(jù)。
多表查詢,需要有相同的兩個表的聯(lián)接條件,該條件放在WHERE子句中,格式為:
select <目標列>from <表明1>,<表名2> where <表名1>.<字段名1>=<表名2>.<字段名2>
1、依據(jù)學號條件查詢學生的各門成績:
select * from [學生$],[課程$] where [學生$].學號=[課程$].學號
為了簡化輸入,在SELECT 命令中允許使用表的別名。為此,可以在FROM 子句中定義一個臨時別名,以便查詢使用。其格式如下:
SELECT <目標列> FROM <表名1><別名1>,<表名2><別名2>WHERE <別名1><字段名1>=<別名2>.<字段名2>
2、依據(jù)學號條件查詢學生的各門成績大于85分
select kc.學號,姓名,課程,成績 from [學生$] xs , [課程$] kc where xs.學號 = kc.學號 and 成績 >85
在數(shù)據(jù)透視表中對多表查詢,還可以使用另一種連接格式,就是內連接查詢,也叫等值連接查詢。它是組合兩個(或多個以上)表,最常使用的方法。其語句如下:
SELECT <目標列> FROM <表名1> inner join <表名2> on <表名1>.<字段名1>=<表名2>.<字段名2>
3、依據(jù)學號條件查詢學生的各門成績大于85分
select kc.學號,姓名,課程,成績 from [學生$]xs inner join [課程$] kc on xs.學號=kc.學號
在內連接查詢中,只有在兩表中同時匹配的行才才能在結果集中選出,而在外連接中可以只限制一個表,而不限制另一個表,其所有的行都都出現(xiàn)在結果集中。外連接分為左外連接,右外連接和全部鏈接。
左連接是對連接條件中左邊的表不加限制;右連接是對右邊的表不加限制;全部連接是對兩個表都不加限制。其語法如下:
select <選擇列數(shù)> from <表名1> <[ lift ︳right ︳full][outer]> jion <表名2> on <表名1>.<列名>=<表名2>.<列名>
1、以[學生$]中記錄為準,[課程$]中不存在的學號也可以列出:
select kc.學號,姓名,課程,成績 from [學生$]xs left join [課程$] kc on xs.學號=kc.學號
2、以[課程$]中記錄為準,[學生$]中不存在的學號也可以列出:
select kc.學號,姓名,課程,成績 from [學生$]xs right join [課程$] kc on xs.學號=kc.學號