VAC用WINDOWS。 CR+LF
任務材料 :
數據1:20W的數據 all_num.txt
格式:13020451023,32523,9135044120,20111101133450,0,0,20120501010101
數據2:2W的數據 filter_num.txt
格式:13020451023
任務目標:
要將20W條數據中剔除掉2W個數據。
步驟1:建表(10‘)
A_TEMP_123 存20W, A存 2W
CREATE TABLE A_TEMP_123
(
A1 VARCHAR2(30),
A2 VARCHAR2(30),
A3 VARCHAR2(30),
A4 VARCHAR2(30),
A5 VARCHAR2(30),
A6 VARCHAR2(30),
A7 VARCHAR2(30)
) ;
CREATE TABLE A
(
i VARCHAR2(30)
);
步驟2:建索引 (5’)
(A_TEMP_123.A1 與A.I存號碼)
CREATE INDEX IDX_A1 ON A_TEMP_123 (A1);
CREATE INDEX IDX_A2 ON A (I);
步驟3:文本格式整理(5‘)
dos2unix *.txt
步驟3:sqlldr 導入(10‘)
sqlldr 賬號/密碼 control=s1.ctl data=all_num.txt log=s1.log errors=10000
s1 內容:
load data
replace into table A_TEMP_123
fields terminated by ','(a1,a2,a3,a4,a5,a6,a7)
sqlldr 賬號/密碼 control=s2.ctl data=filter_num.txt log=s2.log errors=10000
s2 內容:
load data
replace into table A
fields terminated by ','(i)
步驟4:SQL查詢(10’)
2B方法:(半天出不了結果)
select count(1) from A_TEMP_123 t1 where t1.a1 not in (select t2.i from a t2 );
有四種:
1.用 in 關聯子查詢方法 :(比較慢)
SQL> select count(1) from A_TEMP_123 t1 where t1.a1 not in (select t2.i from a t2 where t2.i=t1.a1);
COUNT(1)
----------
203192
如何計算此查詢:SQL Server 通過將每一行的值代入內部查詢,考慮 A_TEMP_123 T1 表中的每一行是否都包括在結果中。
例如,
1:如果 SQL Server 首先檢查 13020451023,32523,9135044120,20111101133450,0,0,20120501010101 行,那麼變量 T1.A1 將取值 13020451023,
2:SQL Server 將該值代入內部查詢。select t2.i from a t2 where t2.i=13020451023,結果爲13020451023,
3:因此外部查詢計算爲:select count(1) from A_TEMP_123 t1 where 13020451023 not in (13020451023),結果爲假,因此不列入生成的新表。
由此可見,加上與不加 where t2.i=t1.a1 的2B算法 ,差別就在於where 13020451023 not in (x1,x2,x3...........xn)的Xn的個數差別,加上條件(關聯查詢)只有一兩個,不加的話在in中有2W個,運算量差了4個數量級啊!
2.用 exists 關聯子查詢方法 :
SQL> select count(1) from A_TEMP_123 t1 where not exists (select 1 from a t2 where t2.i=t1.a1);
COUNT(1)
----------
203192
同理,用exists就更快一點,因爲在select 1 from a t2 where t2.i=13020451023時,返回1,在外部查詢時:select count(1) from A_TEMP_123 t1 where not exists (1),由於使用not exists ,所以存在1 就不被插入新表。
3.用 MINUS方法:
SQL> select count(1) from a_temp_123 t1 where t1.A1 in (select A1 from a_temp_123 minus select i from a);
COUNT(1)
----------
203192
4.用left join方法:
SQL> select count(1) from A_TEMP_123 t1 left join a t2 on t1.a1=t2.i where t2.i is null;
COUNT(1)
----------
203192
步驟5:腳本導出數據(5‘)
#!/bin/sh
sqlplus-s xx/xx<<EOF >/dev/null
set trimspoolon headingoffnewpagenone feedofftermoff
spool after_filter.txt
select a1||','||a2||','||a3||','||a4||','||a5||','||a6||','||a7froma_temp_123 T1
where T1.A1in(select A1froma_temp_123minusselect ifroma);
spooloff
exit;
EOF
步驟6:壓縮
zip after_filter.zipafter_filter.txt
步驟7:下載到本機
解壓,轉換成windows格式!
這次數據提取,讓我懂得2B的SQL語句的執行效率差別有多大,愣是執行了1小時沒出數據,今後要多加強SQL的學習啊。
許多查詢都可以通過執行一次子查詢並將得到的值代入外部查詢的 WHERE 子句中進行計算。在包括相關子查詢(也稱爲重複子查詢)的查詢中,子查詢依靠外部查詢獲得值。這意味着子查詢是重複執行的,爲外部查詢可能選擇的每一行均執行一次。
此查詢在 SalesPerson 表中檢索獎金爲 5000 且僱員標識號與 Employee 和 SalesPerson 表中的標識號相匹配的僱員的名和姓的一個實例。
USE AdventureWorks2008R2; GO SELECT DISTINCT c.LastName, c.FirstName, e.BusinessEntityID FROM Person.Person AS c JOIN HumanResources.Employee AS e ON e.BusinessEntityID = c.BusinessEntityID WHERE 5000.00 IN (SELECT Bonus FROM Sales.SalesPerson sp WHERE e.BusinessEntityID = sp.BusinessEntityID) ; GO
下面是結果集:
LastName FirstName BusinessEntityID
-------------------------- ---------- ------------
Ansman-Wolfe Pamela 280
Saraiva José 282
(2 row(s) affected)
該語句中前面的子查詢無法獨立於外部查詢進行計算。它需要 Employee.BusinessEntityID 值,但是此值隨 SQL Server 檢查Employee 中的不同行而改變。
下面準確說明了如何計算此查詢:SQL Server 通過將每一行的值代入內部查詢,考慮Employee 表中的每一行是否都包括在結果中。例如,如果 SQL Server 首先檢查 Syed Abbas 行,那麼變量Employee.BusinessEntityID 將取值 285,SQL Server 將該值代入內部查詢。
結果爲 0(Syed Abbas 沒有收到獎金,因爲他不是銷售人員),因此外部查詢計算爲:
USE AdventureWorks2008R2;
GO
SELECT LastName, FirstName
FROM Person.Person AS c JOIN HumanResources.Employee AS e
ON e.BusinessEntityID = c.BusinessEntityID
WHERE 5000 IN (0.00)
由於這是假的,因此 Syed Abbas 行不包括在結果中。對 Pamela Ansman-Wolfe 行運行相同的過程,您會發現此行沒有包括在結果中。
通過在外部查詢中引用表中的列作爲表值函數的參數,相關子查詢也可以在 FROM 子句中包含表值函數。在這種情況下,對於外部查詢的每一行,將根據子查詢計算表值函數。
------------------------------------------------------------------------------------------------------------