]]>用SQL Server 2005 实现l果集分?http://www.aygfsteel.com/kylixlu/archive/2008/01/20/176624.html陆昱?/dc:creator>陆昱?/author>Sun, 20 Jan 2008 12:21:00 GMThttp://www.aygfsteel.com/kylixlu/archive/2008/01/20/176624.htmlhttp://www.aygfsteel.com/kylixlu/comments/176624.htmlhttp://www.aygfsteel.com/kylixlu/archive/2008/01/20/176624.html#Feedback0http://www.aygfsteel.com/kylixlu/comments/commentRss/176624.htmlhttp://www.aygfsteel.com/kylixlu/services/trackbacks/176624.html介绍
有了SQL Server 2005之后Q我们用分|询比老版本容易多了。在本文中,我将主要用到的是NorthWind数据库,所以你也可以仿照编写我所列D的范例。我量使例子简单化;因ؓM复杂的东襉K会都会造成h。我从“传统”的方法着手,比如QSELECT, TOPQ然后慢慢进入具体的SQL Server 2005 分页的例子?br />
背景
我常怼被问到这L一个问题或者说一pdq样的问题,“你如何在SQL中进行分?在有很多个记录的情况下,你又如何做,比如10000个记录或者更多呢Q?br />
我思烦着{案。更切地说Q我考虑了更多的问题q且我都认真L考,“q必定是一个普的问题Q每一个开发h员必d理或者说解决的。具有非常大的数据库集的工作和分大是怎样的?从多U表所得到的结果集又是如何Q?#8221;
因此Q我军_具体l合SQL Server 2005来研I这些问题。下面的Ҏ是至今ؓ止最Ҏ的,采纳。但是这是非常罕见的Qƈ非易事?br />
select * from mytable
Where ID between20and30
SQL Top
SQL TopQ从l果集返回记录)非常善于从结果集的每个尾部返回大量的记录?br />
下面的例子通过命oqty获得了前10名顾客。在论坛上这是一个非常普骗的问题。尽TOP也可以拉动一定百分比的记录,但是我们q里不讨论?br />
selecttop10 * from customers -- This is a very basic example.
selectTOP10 Customers.CustomerID, Customers.CompanyName, count(*) OrderCount
from Customers innerjoin Orders on Orders.CustomerID = Customers.CustomerID
GROUPBY Customers.CustomerID, Customers.CompanyName
ORDERBY OrderCount DESC
q是很有用的。当你要把记录从11拉到20Ӟ你就可以使用临时表?br />
-- SELECT First 30 records in to Temp table
SELECTTOP30 * INTO
#TEMP
from Customers
ORDERBY CompanyName ASC
--Select Bottom 10 records in another temp table
SELECTTOP10 *
INTO #TEMP2
from #Temp
ORDERBY CompanyName DESC
-- GET THE RECORDS
SELECT * FROM #TEMP2
q对数前几个页面或者前几个用户是种惩罚。如果拥有这L用户Q他们想从一一之后返回页面,你将以1000条记录返?0条来l束Q这是非怽效的。你可以在第一个时表中内|一个n份,然后用一个SELECT声明来作替代?br />
TOP的替?br />
有一个这LTOP替代Q它使用的是rowcountQ行计数Q。用行计数要小心。如果它不关闭的话,你陷入各U各L困境?br />
SETrowcount10
SELECT * from Customers
ORDERBY CompanyName
WITH, ROW_NUMBER Q行敎ͼand OVER
q对SQL Server 2005来说非常新鲜q且看上去非常有用。下面一个例子显CZ一个结果集得到20?9条记录。刚开始,我有一Ҏ奇,但是我浏览了查询器后我发现它是如此简单?br />
With Cust AS
( SELECT CustomerID, CompanyName,
ROW_NUMBER() OVER (orderby CompanyName) as RowNumber
FROM Customers )
select *
from Cust
Where RowNumber Between20and30
SQL Server 2005的WITH指定了一个时命名的l果Q很像SQL Server以前版本中的临时表。但是,输入部分是ROW_NUMBER和OVER声明Q它Ҏ公司的名U在每组中创数。这像通过命o条文向时表d一个n份种子?br />
我希望你赞成我的看法。如果不Q运行代码ƈ查看l果集。对大表来说速度真的非常?表的速度过250Q?00条记录,Ҏ我留下了深刻的印象?br />
一h合到储存q程?br />
现在我们把它一h合到储存q程Q这个储存过E我们可以通过应用E序来用。我不打展C?NET Datagrid或者相似的控gQ因为是本文探讨范围之外。下面看到的储存q程使用了灵zȝ面大小和页面数目,所以你可以随意地选择M面。这P如果你想跌前十去L某一条记录就非常方便了。下面的例子是从W一开始分늚Q而不是从W?,但也可以随意更改?br />
CREATEPROC GetCustomersByPage
@PageSize int, @PageNumber int
AS
Declare @RowStart int
Declare @RowEnd int
if @PageNumber > 0
Begin
SET @PageNumber = @PageNumber -1
SET @RowStart = @PageSize * @PageNumber + 1;
SET @RowEnd = @RowStart + @PageSize - 1 ;
With Cust AS
( SELECT CustomerID, CompanyName,
ROW_NUMBER() OVER (orderby CompanyName) as RowNumber
FROM Customers )
select *
from Cust
Where RowNumber >= @RowStart and RowNumber <= @RowEnd end
END
q行q个E序Q仅需指定面大小和页数目(GetCustomersByPage, @PageSize and @PageNumber)Q代码如下:
exec GetCustomersByPage 10, 1
]]>SQLServer和Oracle常用函数Ҏhttp://www.aygfsteel.com/kylixlu/archive/2007/12/24/169942.html陆昱?/dc:creator>陆昱?/author>Mon, 24 Dec 2007 01:59:00 GMThttp://www.aygfsteel.com/kylixlu/archive/2007/12/24/169942.htmlhttp://www.aygfsteel.com/kylixlu/comments/169942.htmlhttp://www.aygfsteel.com/kylixlu/archive/2007/12/24/169942.html#Feedback0http://www.aygfsteel.com/kylixlu/comments/commentRss/169942.htmlhttp://www.aygfsteel.com/kylixlu/services/trackbacks/169942.html
1.l对?
S:select abs(-1) value
O:select abs(-1) value from dual
2.取整(?
S:select ceiling(-1.001) value
O:select ceil(-1.001) value from dual
3.取整Q小Q?
S:select floor(-1.001) value
O:select floor(-1.001) value from dual
4.取整Q截取)
S:select cast(-1.002 as int) value
O:select trunc(-1.002) value from dual
5.四舍五入
S:select round(1.23456,4) value 1.23460
O:select round(1.23456,4) value from dual 1.2346
6.e为底的幂
S:select Exp(1) value 2.7182818284590451
O:select Exp(1) value from dual 2.71828182
7.取e为底的对?
S:select log(2.7182818284590451) value 1
O:select ln(2.7182818284590451) value from dual; 1
8.?0为底Ҏ
S:select log10(10) value 1
O:select log(10,10) value from dual; 1
9.取^?
S:select SQUARE(4) value 16
O:select power(4,2) value from dual 16
10.取^Ҏ
S:select SQRT(4) value 2
O:select SQRT(4) value from dual 2
11.求Q意数为底的幂
S:select power(3,4) value 81
O:select power(3,4) value from dual 81
12.取随机数
S:select rand() value
O:select sys.dbms_random.value(0,1) value from dual;
13.取符?
S:select sign(-8) value -1
O:select sign(-8) value from dual -1
14.圆周?
S:SELECT PI() value 3.1415926535897931
O:不知?
15.sin,cos,tan 参数都以弧度为单?
例如Qselect sin(PI()/2) value 得到1QSQLServerQ?
16.Asin,Acos,Atan,Atan2 q回弧度
17.弧度角度互换(SQLServerQOracle不知?
DEGREESQ弧?〉角?
RADIANSQ角?〉弧?
数值间比较Q?br />
18. 求集合最大?
S:select max(value) value from
(select 1 value
union
select -2 value
union
select 4 value
union
select 3 value)a
O:select greatest(1,-2,4,3) value from dual
19. 求集合最?
S:select min(value) value from
(select 1 value
union
select -2 value
union
select 4 value
union
select 3 value)a
O:select least(1,-2,4,3) value from dual
20.如何处理null?F2中的null?0代替)
S:select F1,IsNull(F2,10) value from Tbl
O:select F1,nvl(F2,10) value from Tbl
21.求字W序?
S:select ascii('a') value
O:select ascii('a') value from dual
22.从序h字符
S:select char(97) value
O:select chr(97) value from dual
23.q接
S:select '11'+'22'+'33' value
O:select CONCAT('11','22') 33 value from dual
23.子串位置 --q回3
S:select CHARINDEX('s','sdsq',2) value
O:select INSTR('sdsq','s',2) value from dual
23.模糊子串的位|?--q回2,参数L中间%则返?
S:select patindex('%d%q%','sdsfasdqe') value
O:oracle没发玎ͼ但是instr可以通过W四个参数控制出现次?
select INSTR('sdsfasdqe','sd',1,2) value from dual q回6
24.求子?
S:select substring('abcd',2,2) value
O:select substr('abcd',2,2) value from dual
25.子串代替 q回aijklmnef
S:SELECT STUFF('abcdef', 2, 3, 'ijklmn') value
O:SELECT Replace('abcdef', 'bcd', 'ijklmn') value from dual
26.子串全部替换
S:没发?
O:select Translate('fasdbfasegas','fa','? ) value from dual
27.长度
S:len,datalength
O:length
28.大小写{?lower,upper
29.单词首字母大?
S:没发?
O:select INITCAP('abcd dsaf df') value from dual
30.左补I格QLPAD的第一个参CؓI格则同space函数Q?
S:select space(10)+'abcd' value
O:select LPAD('abcd',14) value from dual
31.双I格QRPAD的第一个参CؓI格则同space函数Q?
S:select 'abcd'+space(10) value
O:select RPAD('abcd',14) value from dual
32.删除I格
S:ltrim,rtrim
O:ltrim,rtrim,trim
33. 重复字符?
S:select REPLICATE('abcd',2) value
O:没发?
34.发音怼性比?q两个单词返回gP发音相同)
S:SELECT SOUNDEX ('Smith'), SOUNDEX ('Smythe')
O:SELECT SOUNDEX ('Smith'), SOUNDEX ('Smythe') from dual
SQLServer中用SELECT DIFFERENCE('Smithers', 'Smythers') 比较soundex的差
q回0-4Q?为同韻I1最?
日期函数Q?br />
35.pȝ旉
S:select getdate() value
O:select sysdate value from dual
36.前后几日
直接与整数相加减
37.求日?
S:select convert(char(10),getdate(),20) value
O:select trunc(sysdate) value from dual
select to_char(sysdate,'yyyy-mm-dd') value from dual
38.求时?
S:select convert(char(8),getdate(),108) value
O:select to_char(sysdate,'hh24:mm:ss') value from dual
参数---------------------------------下表需要补?
year yy, yyyy
quarter qq, q (季度)
month mm, m (m O无效)
dayofyear dy, y (O表星?
day dd, d (d O无效)
week wk, ww (wk O无效)
weekday dw (O不清?
Hour hh,hh12,hh24 (hh12,hh24 S无效)
minute mi, n (n O无效)
second ss, s (s O无效)
millisecond ms (O无效)
----------------------------------------------
40.当月最后一?
S:不知?
O:select LAST_DAY(sysdate) value from dual
41.本星期的某一天(比如星期日)
S:不知?
O:SELECT Next_day(sysdate,7) vaule FROM DUAL;
42.字符串{旉
S:可以直接转或者select cast('2004-09-08'as datetime) value
O:SELECT To_date('2004-01-05 22:09:38','yyyy-mm-dd hh24-mi-ss') vaule FROM DUAL;
43.求两日期某一部分的差Q比如秒Q?
S:select datediff(ss,getdate(),getdate()+12.3) value
O:直接用两个日期相减(比如d1-d2=12.3Q?
SELECT (d1-d2)*24*60*60 vaule FROM DUAL;
44.Ҏ差值求新的日期Q比如分钟)
S:select dateadd(mi,8,getdate()) value
O:SELECT sysdate+8/60/24 vaule FROM DUAL;
45.求不同时区时?
S:不知?
O:SELECT New_time(sysdate,'ydt','gmt' ) vaule FROM DUAL;