2,解决个体(您可以使用的方法,您可以从这些基本的方法组合或扩展最终达到您的查询要求)
    (
1)一些简单问题中可以使用的技巧,您可以通过运行语句看看它们得到了什么
        a.   
       
------------------------------------------------------
DECLARE @str
SET @str=’aaa,bbbx,eee,vv’
SELECT LEN(REPLACE(@str,’,’,’,,’)-LEN(@str)

b.
------------------------------------------------------
DECLARE @b BIT
   
SET @b=0
SELECT SUBSTRING(‘否是’,@b+1,1)
c.   (
2-1.c)
------------------------------------------------------
DECLARE @ids
SET @ids=1,3
SELECT * FROM UserInfo WHERE CHARINDEX(‘,’+RTRIM(id) +’,’ , ‘,’+@ids+’,’)>0    --考滤一下,这里为什么要在字串及ID前后加上逗号
D
------------------------------------------------------
SELECT * INTO t1 FROM UserInfo WHERE 1=0
依然同上文,不一一列举
    (
2)常用解决问题的方法
        a. 您需要准备一个Split函数
           
create function f_split(@str varchar(8000),@StrSeprate varchar(10))
returns @temp table(a varchar(100))
as
begin
   
declare @i int
   
set @str=rtrim(ltrim(@SourceSql))
   
set @i=charindex(@StrSeprate,@str)
   
while @i>=1
   
begin
       
insert @temp values(left(@str,@i-1))
       
set @str=substring(@str,@i+1,len(@str)-@i)    --当然,这里您也可以改写为STUFF,可以自己试着改写一下
        set @i=charindex(@StrSeprate,@str)
   
end
   
if @SourceSql<>'\\'
      
insert @temp values(@str)
   
return
end


--用法:select * from dbo.f_split('A:B:C:D:E',':')
            请保留它,在很多场合,很多时候您都会用到它.因为它是个通用且有用的函数

        b.利用创建临时表生成连续ID.
           
SELECT *,IDENTITY(INT) NID INTO #t FROM tb
利用临时表,当有了从
1--你的记录数连续的NID时,NID就是标识,用一个变量作指针 你就可以用循环来操作每一条记录了.
也可以跳至任一条记录.还可以利用NID来记录行之间的前后关系,这在一些查询中非常有效,比如先进先出的设计
        c.利用sp_executesql得到某些查询结果再参与运算
        d.使用INSERT
SELECT 还是 SELECT INTO
        e.
CASE variable WHEN 或是 CASE WHE condition  statement THEN
        f. 利用COUNT生成序数
ID    UserName    ClassID    Score
1    Aaa    9802    66
2    Bbb    9801    70
3    Ccc    9801    69
4    ddd    9801    88
            设Score 不重复,得到每个 UserName 的 Score排名
2-2.f.1
           
------------------------------------------------------
SELECT UserName,
(
SELECT COUNT(*) FROM Student WHERE Score>=a.Score)
FROM Student a
每查询一条记录时,从表中统计Score大于等于(因为设Score不重复,所以等于指它本身)当前记录的个数. 因此得到排名

当Score有重复值时, 名次也会有重复值,并且会出现名次断号,此时需要进一一步处理
2-2.f.2
SELECT DISTINCT Score INTO #t FROM Student
SELECT a.UserName,b.Index
   
FROM student a
INNER JOIN
    (
SELECT Score,
        (
SELECT COUNT(*) FROM #t WHERE Score>=a.Score) Index
       
FROM #t a
    ) b
   
ON a.Score=b.Score
DROP TABLE #t
这样得到了不间断的排名. 仔细看语句,这里临时表#t没有做任何处理,仅起到了暂存数据的作用, 以此来简化SQL查询语句. 您可以尝试将#t用生成它的那句SELECT查询代替,用一条SQL语句来实现这个功能(如果用了子查询代替#t, 参考我上面对虚表的说法,更容易理解, 临时表换成虚表).
(注.这里不是鼓励使用一条SQL查询完成,而是建议您在学习时这样做,提高自己的熟练程度. 而在实际应用中是否应该用一条语句要具体问题具体分析)


得到每个班级Score最高的前两名学生的记录
2-2.f.3
-----------------------------------------------------------
SELECT * FROM Student a
   
WHERE 2>(SELECT COUNT(1) FROM Student WHERE Score>a.Score AND ClassID=a.ClassID)
您还到想到其它简洁的写法吗?(当然有,提示
IN 关健字)
请对比2
-2.f.1这条语句去理解2-2.f.3的语句思路. 思考,这语句有什么问题吗?
(提示.当同一ClassID的Score有重复值时,确定是每个班级2条记录吗? 如果不是,如何解决? 参见
2-2.f.2).
        g.由
2-2.f.1您如何解决下面的问题:
            Product 表中Num字段记录了每天的入库数,请更新 AllNum字段为截止当前的库存数
LogDate    Num    AllNum
2006-6-1    100   
2006-6-3    20   
2006-7-5    300   
       
2-2-g.1   
UPDATE a SET AllNUM=
(
SELECT SUM(Num) FROM Product b WHERE b.LogDATE<=a.LogDate) FROM product a
        它与2
-2.f.1有区别吗? 理解之后,您应该会说”没有区别”

h.行转列.
网上有很多例子,随便都可以找一个单表的下来. 静态(要转的列固定)行转列比较容易理解也容易做到,动态行转列,只需您将构建的SQL字串PRINT仔细分析,相信聪明好学的您一定会发现原理. 理解了它的得来,再复杂的行转列也只是多连表,多统计,增加点语句长度而已.

i.递规查询变量
2-2.i.1
DECLARE @s VARCHAR(1000)
SET @s=’’
SELECT @s=@s + ‘,’ + RTRIM(id) FROM Student
SELECT @s=STUFF(@s,1,1,’’)
RPINT
@s
/*得到结果
1,2,3,4
*/
为什么会得到这样的结果? 难道因为它叫递规查询变量? 那么它为什么要叫递规查询变量? 呵呵.

j.除上述方法外,您需要心中常记一些二维模型,遇到问题时看能否把问题转化.
   
2-2.j.1
    二表
class1
------------------
id name total
1  aaa  90
2  bbb  98
3  ccc  89
------------------
class2
------------------
id name total
1  zzz  24
2  aaa  77
3  xxx  99
要这样结果:
id name total class
1  xxx   99   class2
2  bbb   98   class1
1  aaa   90   class1
3  ccc   89   class1
参照
1-5.2您可以写出查询来。

表名:table1
字段及内容:
id   classtitle    recorder
1    生活百科      科学
2    生活百科      饮食
3    体育在线      足球
4    体育在线      篮球
5    新闻周刊      国际
6    新闻周刊      国内
7    生活百科      穿衣
........
要求得到:

生活百科
 
--科学
  --饮食
  --穿衣
体育在线
 
--足球
  --篮球
新闻周刊
 
--国际
  --国内

心中想到模型(二级分类)
Id    sid            parentid
?    新闻周刊      新闻周刊
?    体育在线      体育在线
?    生活百科      生活百科
1    生活百科      科学
2    生活百科      饮食
3    体育在线      足球
4    体育在线      篮球
5    新闻周刊      国际
6    新闻周刊      国内
7    生活百科      穿衣
2-2.j.2
SELECT DISTINCT classtitle,ct=classtitle,dot='' FROM table1
   
UNION
SELECT classtitle,recorder,dot='--' FROM table1
   
ORDER BY classtitle
您需要保留记住一些常用二维模型,在解决问题时考滤问题是否能向相应的模型转换。

    这一节也不再例举,more practise more progress.
posted on 2008-03-12 15:14  skins  阅读(133)  评论(0)    收藏  举报