全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1736
推到 Plurk!
推到 Facebook!

SQL2000 Query 技巧考驗效能,試試你的功力

答題得分者是:Mickey
shpeng
初階會員


發表:6
回覆:67
積分:49
註冊:2002-12-21

發送簡訊給我
#1 引用回覆 回覆 發表時間:2002-12-23 12:10:12 IP:61.219.xxx.xxx 未訂閱
FOR SQL2000 用 [TableA] Query出如 [TableB] 的結果
此範例適用於 報價,薪資異動....等 須要保留歷史資料的應用    建議不使用 DECLARE CURSOR 命令,因為它很[慢...長]    [TableA]
Id        Name        aDay
=======================
1        A        1/5
2        A        1/5        <----最後報價
3        B        1/5        <----最後報價
4        C        1/2
5        B        1/3
6        C        1/4        <----最後報價
7        C        1/1
8        A        1/3    [TableB]
Id        Name        aDay
=======================
2        A        1/5
3        B        1/5
6        C        1/4
發表人 -
------
==取之於斯,用之於斯==
delphiwww
資深會員


發表:145
回覆:363
積分:368
註冊:2002-03-13

發送簡訊給我
#2 引用回覆 回覆 發表時間:2002-12-23 13:31:11 IP:202.145.xxx.xxx 未訂閱
SELECT b.name, b.aday, MAX(id) FROM (SELECT name, MAX(aday) AS aday         FROM [TableA]         GROUP BY name) AS a, [TableA] b WHERE a.name = b.name AND a.aday = b.aday GROUP BY b.name, b.aday    
引言:
FOR SQL2000 用 [TableA] Query出如 [TableB] 的結果
此範例適用於 報價,薪資異動....等 須要保留歷史資料的應用    建議不使用 DECLARE CURSOR 命令,因為它很[慢...長]    [TableA]
Id        Name        aDay
=======================
1        A        1/5
2        A        1/5        <----最後報價
3        B        1/5        <----最後報價
4        C        1/2
5        B        1/3
6        C        1/4        <----最後報價
7        C        1/1
8        A        1/3    [TableB]
Id        Name        aDay
=======================
2        A        1/5
3        B        1/5
6        C        1/4
發表人 - >< face="Verdana, Arial, Helvetica">
Mickey
版主


發表:77
回覆:1882
積分:1390
註冊:2002-12-11

發送簡訊給我
#3 引用回覆 回覆 發表時間:2002-12-23 14:33:14 IP:61.219.xxx.xxx 未訂閱
SELECT A.id,A.name,A.aday FROM TableA A where aday convert(char,id)=(select max(aday convert(char,id)) from TableA where name=A.name)
引言:
FOR SQL2000 用 [TableA] Query出如 [TableB] 的結果
此範例適用於 報價,薪資異動....等 須要保留歷史資料的應用    建議不使用 DECLARE CURSOR 命令,因為它很[慢...長]    [TableA]
Id        Name        aDay
=======================
1        A        1/5
2        A        1/5        <----最後報價
3        B        1/5        <----最後報價
4        C        1/2
5        B        1/3
6        C        1/4        <----最後報價
7        C        1/1
8        A        1/3    [TableB]
Id        Name        aDay
=======================
2        A        1/5
3        B        1/5
6        C        1/4
發表人 - >< face="Verdana, Arial, Helvetica"> /* 使用中文很辛苦,中華男兒當自強 */
delphiwww
資深會員


發表:145
回覆:363
積分:368
註冊:2002-03-13

發送簡訊給我
#4 引用回覆 回覆 發表時間:2002-12-23 15:43:40 IP:202.145.xxx.xxx 未訂閱
拍拍手,好厲害
引言: SELECT A.id,A.name,A.aday FROM TableA A where aday convert(char,id)=(select max(aday convert(char,id)) from TableA where name=A.name)
引言:
FOR SQL2000 用 [TableA] Query出如 [TableB] 的結果
此範例適用於 報價,薪資異動....等 須要保留歷史資料的應用    建議不使用 DECLARE CURSOR 命令,因為它很[慢...長]    [TableA]
Id        Name        aDay
=======================
1        A        1/5
2        A        1/5        <----最後報價
3        B        1/5        <----最後報價
4        C        1/2
5        B        1/3
6        C        1/4        <----最後報價
7        C        1/1
8        A        1/3    [TableB]
Id        Name        aDay
=======================
2        A        1/5
3        B        1/5
6        C        1/4
發表人 - >< face="Verdana, Arial, Helvetica"> /* 使用中文很辛苦,中華男兒當自強 */
Mickey
版主


發表:77
回覆:1882
積分:1390
註冊:2002-12-11

發送簡訊給我
#5 引用回覆 回覆 發表時間:2002-12-23 15:48:15 IP:61.219.xxx.xxx 未訂閱
哪兒的話兒 <>< face="Verdana, Arial, Helvetica">引言: 拍拍手,好厲害
引言: SELECT A.id,A.name,A.aday FROM TableA A where aday convert(char,id)=(select max(aday convert(char,id)) from TableA where name=A.name)
引言:
FOR SQL2000 用 [TableA] Query出如 [TableB] 的結果
此範例適用於 報價,薪資異動....等 須要保留歷史資料的應用    建議不使用 DECLARE CURSOR 命令,因為它很[慢...長]    [TableA]
Id        Name        aDay
=======================
1        A        1/5
2        A        1/5        <----最後報價
3        B        1/5        <----最後報價
4        C        1/2
5        B        1/3
6        C        1/4        <----最後報價
7        C        1/1
8        A        1/3    [TableB]
Id        Name        aDay
=======================
2        A        1/5
3        B        1/5
6        C        1/4
發表人 - >< face="Verdana, Arial, Helvetica"> /* 使用中文很辛苦,中華男兒當自強 */
/* 使用中文很辛苦,中華男兒當自強 */
shpeng
初階會員


發表:6
回覆:67
積分:49
註冊:2002-12-21

發送簡訊給我
#6 引用回覆 回覆 發表時間:2002-12-24 09:17:11 IP:211.72.xxx.xxx 未訂閱
若將資料增加到10萬筆,各欄位都建立 Index 
連續跑10圈 (儘量排除Disk I/O干擾,載入快取)
經測試結果
        delphiwww        4,969 ms
        Mickey                38,225 ms            分析結果
        delphiwww        雖然用了2個TmpTable,看來似乎比較慢
                        但發揮了Index功能 So 較快
                        若TableA[id,Name,aDay,f01,f02,f03,f04,...等附加欄位] 不適用             Mickey                只用1個TmpTable
                        aday convert(char,id)需大量運算,Index功能失效
                        aday convert(char,id) <--- aday 格式 mm/dd/yyyy 會誤判 
                        很有創意的方法..成功
                        
                        Index 問題 有解嗎???    --測試語法------------------------
DECLARE @t1 datetime
DECLARE @p1 int
DECLARE @p2 int
SET @p1 = 0
SET @p2 = 0
DECLARE @i        INT
SET @i = 0
WHILE @i < 10
BEGIN            SET @t1 = getdate()
        --delphiwww的程式命令---------------
                SELECT b.name, b.aday, MAX(id)
                FROM (SELECT name, MAX(aday) AS aday FROM [TableA] GROUP BY name) AS a, [TableA] b
                WHERE a.name = b.name AND a.aday = b.aday
                GROUP BY b.name, b.aday
        ----------------------------------------------------
        SET @p1 = @p1   datediff(millisecond,@t1,getdate())            SET @t1 = getdate()
        --Mickey的程式命令----------------------
                SELECT A.id,A.name,A.aday
                FROM TableA A
                --原where aday convert(char,id)=(select max(aday convert(char,id)) 
                where convert(char,aday,121) convert(char,id)=(select max(convert(char,aday,121) convert(char,id)) 
                from TableA where name=A.name) 
        -------------------------------------------------------
        SET @p2 = @p2   datediff(millisecond,@t1,getdate())    SET @i = @i 1
END
SELECT @p1,@p2
發表人 - shpeng 於 2002/12/24 09:43:22
------
==取之於斯,用之於斯==
Mickey
版主


發表:77
回覆:1882
積分:1390
註冊:2002-12-11

發送簡訊給我
#7 引用回覆 回覆 發表時間:2002-12-24 10:43:58 IP:61.219.xxx.xxx 未訂閱
這樣應該會比較好些 SELECT max(A.id) as id,A.name,A.aday FROM TableA A where aday=(select max(aday) from TableA where name=A.name) group by A.name, A.aday order by A.name /* 使用中文很辛苦,中華男兒當自強 */
shpeng
初階會員


發表:6
回覆:67
積分:49
註冊:2002-12-21

發送簡訊給我
#8 引用回覆 回覆 發表時間:2002-12-24 11:29:25 IP:61.219.xxx.xxx 未訂閱
這樣也可以,當TableA 擴充欄位也沒關係    
SELECT d.*
FROM (
        SELECT MAX(id) as id
        FROM (
                SELECT name, MAX(aday) AS aday
                FROM [TableA]
                GROUP BY name
        ) AS a
        , [TableA] b
        WHERE a.name = b.name AND a.aday = b.aday
        GROUP BY b.name, b.aday
        ) AS c
,[TableA] d
WHERE c.id=d.id
發表人 - shpeng 於 2002/12/24 12:00:37
------
==取之於斯,用之於斯==
isthatu
初階會員


發表:80
回覆:47
積分:25
註冊:2002-06-26

發送簡訊給我
#9 引用回覆 回覆 發表時間:2002-12-25 10:53:54 IP:202.145.xxx.xxx 未訂閱
引言: 這樣應該會比較好些 SELECT max(A.id) as id,A.name,A.aday FROM TableA A where aday=(select max(aday) from TableA where name=A.name) group by A.name, A.aday order by A.name /* 使用中文很辛苦,中華男兒當自強 */
(I) SELECT MIN(A.id) as id,A.name,A.aday ^^^^^^^^^ FROM TableA A where aday=(select max(aday) from TableA where name=A.name) group by A.name, A.aday order by A.name (II) SELECT A.id,A.name,A.aday FROM TableA A where aday=(select max(aday) from TableA where name=A.name) group by A.name, A.aday,A.ID ^^^^^^^^^^^^^^^^^^^ order by A.name 請教一下 為何要用max(A.ID) 我改用(II) MIN(A.ID) 或方法(ii)把三個欄位都group by進去 結果都一樣 可能理解力的關係 我比較駑鈍 (II)的語意點較能用文法上去理解 可(I)及原述的語法很難理解 這之間有啥差異 又 (III)不加入group by SELECT A.id,A.name,A.aday FROM TableA A where A.aday=(select max(aday) from TableA where name=A.name) order by A.name 結果一樣.....(語法上這樣是我最容易懂得 效率如何變不得而知) 發表人 - isthatu 於 2002/12/25 11:23:43
------
BCDEFHIJKLMNOPQRSTUVWXZ
Mickey
版主


發表:77
回覆:1882
積分:1390
註冊:2002-12-11

發送簡訊給我
#10 引用回覆 回覆 發表時間:2002-12-25 11:39:36 IP:61.219.xxx.xxx 未訂閱
引言:
引言: 這樣應該會比較好些 SELECT max(A.id) as id,A.name,A.aday FROM TableA A where aday=(select max(aday) from TableA where name=A.name) group by A.name, A.aday order by A.name /* 使用中文很辛苦,中華男兒當自強 */
(I) SELECT MIN(A.id) as id,A.name,A.aday ^^^^^^^^^ FROM TableA A where aday=(select max(aday) from TableA where name=A.name) group by A.name, A.aday order by A.name (II) SELECT A.id,A.name,A.aday FROM TableA A where aday=(select max(aday) from TableA where name=A.name) group by A.name, A.aday,A.ID ^^^^^^^^^^^^^^^^^^^ order by A.name 請教一下 為何要用max(A.ID) 我改用(II) MIN(A.ID) 或方法(ii)把三個欄位都group by進去 結果都一樣 可能理解力的關係 我比較駑鈍 (II)的語意點較能用文法上去理解 可(I)及原述的語法很難理解 這之間有啥差異 又 (III)不加入group by SELECT A.id,A.name,A.aday FROM TableA A where A.aday=(select max(aday) from TableA where name=A.name) order by A.name 結果一樣.....(語法上這樣是我最容易懂得 效率如何變不得而知) 發表人 - isthatu 於 2002/12/25 11:23:43
以 Sample Data 而言,(I)/(II)及(III)都無法得到預期的結果. (I): 會得到 ( 因取 min(id) ) 1 A 1/5 3 B 1/5 6 C 1/4 (II):會得到 ( 因 group 條件含進 id ,致第一筆與第二筆區隔開) 1 A 1/5 2 A 1/5 3 B 1/5 6 C 1/4 (III):會和(II)結果一樣 /* 使用中文很辛苦,中華男兒當自強 */
系統時間:2024-05-15 5:30:18
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!