补充1: 以上是对的,但若将full join 改为 join 就会出错.

解决方案 »

  1.   

    注意其中的***** xx *******部分问题描述:
    1.如果将aa处的full join,改为join,则出错
    2.如果将aa处的full join,改为join,同时修改bb处,取消条件:
      and aa.afields=bb.bfields   
      则正确,大家分析一下是什么原因?
      

  2.   

    补充2: 若将 aa,bb的内容分别先存到临时表,再用临时表来join也是可以的
    补充3: 
    最后几行
    on aa.id=bb.id and aa.afields=bb.bfields   --********** bb *********
    where aa.id is not null
    ) b on a.id=b.id
    若改成on aa.id=bb.id --and aa.afields=bb.bfields   --********** bb *********
    where aa.id is not null
    ) b on a.id=b.id也是可以的,但结果就不对了。
      

  3.   

    这么长?那么多substring,头晕。大概看了一下,好像是因为join 消除了哪笔记录。
      

  4.   

    哦,长是长点,但结构清晰,且能COPY到查询分析器中直接运行。
      

  5.   

    不对,根本没错。
    我把 aa、bb视图内容 Insert 到一张临时表里就什么都好使了!!
      

  6.   

    --帮你断下括号:不然没对齐每办法快速定位:
    declare @t1 table(id int,afields varchar(30))
    insert into @t1
    select 1,'A+B+C'
    union all select 2,'B+C'
    union all select 3,'A+C'
    union all select 4,'C'
    union all select 5,'B+A'declare @t2 table(id int,bfields varchar(30))
    insert into @t2
    select 1,'A+D+C'
    union all select 2,'A+W'
    union all select 3,'D+C'
    union all select 4,'D+F+C'
    union all select 5,'C+D'--查询处理
    select a.* 
    from @t2 a
    join
    (
    select distinct bb.id from
    (
    select a.id,afields=substring(afields,b.id,charindex('+',afields+'+',b.id)-b.id)
    from @t1 a, (
    select id=a.id+b.id from
    (
    select id=0 union all select 1 union all select 2 union all select 3 union all select 4
    union all select 5 union all select 6 union all select 7 union all select 8 union all select 9
    )a,
    (
    select id=0 union all select 10 union all select 20 union all select 30 union all select 40
    union all select 50 union all select 60 union all select 70 union all select 80 union all select 90
    ) b
    ) b where substring('+'+afields,b.id,1)='+'
    ) aa 
    full join
    (  --*************** aa ***********************
    select a.id,bfields=substring(bfields,b.id,charindex('+',bfields+'+',b.id)-b.id)
    from @t2 a ,
    (
    select id=a.id+b.id from
    (
    select id=0 union all select 1 union all select 2 union all select 3 union all select 4
    union all select 5 union all select 6 union all select 7 union all select 8 union all select 9
    )a,
    (
    select id=0 union all select 10 union all select 20 union all select 30 union all select 40
    union all select 50 union all select 60 union all select 70 union all select 80 union all select 90
    ) b
    ) b where substring('+'+bfields,b.id,1)='+'
    )bb on aa.id=bb.id and aa.afields=bb.bfields   --********** bb *********
    where aa.id is not null
    ) b on a.id=b.id/*--测试结果id          bfields                        
    ----------- ------------------------------ 
    1           A+D+C
    3           D+C
    4           D+F+C(所影响的行数为 3 行)
    --*/
      

  7.   

    好玩,我妄图用left join 和right join 找出问题出在哪边,但但但。。真好玩。。
      

  8.   

    好像是Cross join 导致的问题。他在分析的时候可能以为有外连接,然后不知道怎么执行执行出了错误结果。。指定了外连接以后分析的话直接用外连接分析,它就不出错了!!!
    我 把 
    (
    select id=a.id+b.id from
    (
    select id=0 union all select 1 union all select 2 union all select 3 union all select 4
    union all select 5 union all select 6 union all select 7 union all select 8 union all select 9
    )a,
    (
    select id=0 union all select 10 union all select 20 union all select 30 union all select 40
    union all select 50 union all select 60 union all select 70 union all select 80 union all select 90
    ) b
    )
    这个视图替换以后就好使了。
    中间我 尝试使用不同的outer join 来确定问题所在,发现排除了
     aa.afields =bb.bfields 条件进行join 时写法是标准写法时无差别均可得出结果,使用 *= 或=* 时会提示“在包含已联接的表的查询中,不能指定外联接操作符。”SQL Servr 疯了。
      

  9.   

    我也有个很怪的问题
    执行下面的语句
    --------------------------------------------------
    select 厂内料号
     from 
          (
             select 厂内料号,convert(int,substring(厂内料号,charindex('-',厂内料号,1)+1,len(厂内料号)-8-charindex('-',厂内料号,1))) as 层数,floor(round(1/单PCS重量,0)) as 块数             --注意*****  floor(round(1/单PCS重量,0))
             from tblproduct_num where 单PCS重量 is not null and 单PCS重量<>0
          ) as a
     where a.层数='4' and a.块数=6
    ---------------------------------------------
    报错
    Divide by zero error encountered.但我执行
     select 厂内料号,convert(int,substring(厂内料号,charindex('-',厂内料号,1)+1,len(厂内料号)-8-charindex('-',厂内料号,1))) as 层数,floor(round(1/单PCS重量,0)) as 块数 from tblproduct_num where 单PCS重量 is not null and 单PCS重量<>0又没问题郁闷了半天
    不知道sql server中嵌套语句是如何判断where 条件的
     
      

  10.   

    --还有一个order by的问题,供大家研究,注意其中的********标注部分
    --测试数据
    create table a表([产品编号] varchar(4),[产品名称] varchar(10),[产品种类] varchar(1))
    insert into a表
    select '1001','a01','a'
    union all select '1002','a02','a'
    union all select '1003','a03','a'
    union all select '1004','b01','b'
    union all select '1005','b02','b'
    union all select '1006','b03','b'create table b表([客户编号] varchar(3),[产品编号] varchar(4),[数量] int,[时间] datetime)
    insert into b表
    select '001','1001',100,'2003-07-18'
    union all select '001','1003',200,'2003-11-02'
    union all select '001','1005',60,'2003-12-06'
    union all select '002','1002',30,'2003-01-01 '
    union all select '002','1005',500,'2003-12-07'
    union all select '003','1003',70,'2003-02-05'
    union all select '003','1004',500,'2003-06-02'
    union all select '003','1006',20,'2003-06-02'
    union all select '004','1002',110,'2003-02-09'
    union all select '005','1001',22,'2003-03-07'
    union all select '005','1006',20,'2003-06-01'
    go--处理的存储过程
    create proc p_qry
    @开始年月 varchar(6), --查询的开始年月,格式:YYYYMM
    @结束年月 varchar(6)=null, --查询的结束年月,如果不指定(NULL),则与结束年月相同
    @产品种类 varchar(10)='<全部>' --查询的产品种类,为<全部>是,不限制产品种类
    as
    set nocount on
    declare @s varchar(8000),@tj varchar(1000)
    ,@d1 datetime,@d2 datetime,@i intselect @s=''
    ,@d1=@开始年月+'01'
    ,@d2=dateadd(month,1,isnull(@结束年月,@开始年月)+'01')
    ,@tj=case @产品种类 when '<全部>' then ''
    else 'where 产品种类='''+@产品种类+'''' endselect @s=@s+',['+left(dt,4)+'年'+right(dt,2)+'月]=sum(case 时间 when '''
    +dt+''' then 数量 else 0 end)'
    from(
    select dt=convert(varchar(6),dateadd(month,a.id+b.id,@d1),112)
    from(
    select id=0 union all select 1 union all select 2
    union all select 3 union all select 4 union all select 5
    union all select 6 union all select 7 union all select 8
    union all select 9 union all select 10 union all select 11
    ) a,(select id=0 union all select 12 union all select 24 
    union all select 36 union all select 48 union all select 60
    union all select 72 union all select 84 union all select 96
    union all select 108 union all select 120 union all select 132
    ) b where (a.id+b.id)<datediff(month,@d1,@d2)
    ) a --order by dt  --********* 不加order by正常.加上则不能出现正确的结果 ********exec('select 产品名称=case grouping(产品名称) when 1 then ''合计'' else 产品名称 end
    '+@s+',合计=sum(数量)
    from(
    select a.产品名称,b.数量,时间=convert(varchar(6),b.时间,112)
    from a表 a join b表 b on a.产品编号=b.产品编号
    '+@tj+'
    ) a group by 产品名称 with rollup')
    go--调用示例
    exec p_qry '200311','200402'
    go--删除测试
    drop proc p_qry
    drop table a表,b表/*--测试结果
    产品名称       2003年11月    2003年12月    2004年01月    2004年02月    合计          
    ---------- ----------- ----------- ----------- ----------- ----------- 
    a01        0           0           0           0           122
    a02        0           0           0           0           140
    a03        200         0           0           0           270
    b01        0           0           0           0           500
    b02        0           560         0           0           560
    b03        0           0           0           0           40
    合计         200         560         0           0           1632
    --*/
      

  11.   

    昏,
    不过有一点:加不加order by 的结果不一样是肯定的。测试:
    create table t1(a int)
    insert t1 values(3)
    insert t1 values(1)
    insert t1 values(2)declare @s varchar(10)
    set @s = ''
    select @s = @s + cast(a as varchar) from t1 order by a
    select @s
               
    ---------- 
    312(所影响的行数为 1 行)declare @s varchar(10)
    set @s = ''
    select @s = @s + cast(a as varchar) from t1 order by a
    select @s
    ---------- 
    123(所影响的行数为 1 行)
      

  12.   

    select @s=@s+',['+left(dt,4)+'年'+right(dt,2)+'月]=sum(case 时间 when '''
    +dt+''' then 数量 else 0 end)'
    from(
    select top 100 percent
     dt=convert(varchar(6),dateadd(month,a.id+b.id,@d1),112)
    from(
    select id=0 union all select 1 union all select 2
    union all select 3 union all select 4 union all select 5
    union all select 6 union all select 7 union all select 8
    union all select 9 union all select 10 union all select 11
    ) a,(select id=0 union all select 12 union all select 24 
    union all select 36 union all select 48 union all select 60
    union all select 72 union all select 84 union all select 96
    union all select 108 union all select 120 union all select 132
    ) b where (a.id+b.id)<datediff(month,@d1,@d2)
    order by dt) a 
    order by dt  这种内部联接生成的表,
    且ORDER BY不是本身的列的时候,默认为ORDER BY最后一个。
    在内部先排序,就行了。
      

  13.   

    反正是可以了,我也不知道是BUG,还是我概念没清楚。
      

  14.   

    declare @s varchar(8000)
    set @s=''只要加上top 100 percent就行了!
    应该.可能.也许.说不定是语句自动优化过程中的问题。
    declare @s varchar(8000)
    set @s=''
    select @s=@s+s from (
    select top 100 percent rtrim(a.id+B.id)+',' as s
    from 
    (select id=0 union all select 1 union all select 2) A,
    (select id=0 union all select 12 union all select 24) b
    ) s 
    order by s
    print @s
      

  15.   

    同样的道理,你标题上语句:
    上下各加上:
    top 100 percentselect top 100 percent
    a.id,afields=substring(afields,b.id,charindex('+',afields+'+',b.id)-b.id)用JOIN也不会了。
      

  16.   

    个人想象(想当然的):
    就是SQLSERVER的自动优化程序中的内部处理机制问题。
    SQLSERVER不一定是先生成结果再处理的。
    用了TOP 100 percent强迫它先生成结果集。再联接。
      

  17.   

    马可 说:
    top 100 percent
    j9988 说:
    就是SQLSERVER的自动优化程序中的排序问题。SQLSERVER不一定是先生成结果再处理的。
    马可 说:
    有意思
    j9988 说:
    是边生成结果边处理。
    j9988 说:
    所以会出现这个问题。
    j9988 说:
    用了TOP 100 percent强迫它先生成结果集。再联接。
    j9988 说:
    这样就好了。
    马可 说:
    不知道哪些情况是先生成结果集再联接哪些情况下是先连接后生成结果集
    马可 说:
    SQL中有没有这方面的介绍资料 
    j9988 说:
    就是。但以后碰到这种两表以上联接生成结果集,且列也不是原列时(组合生成的)。就要注意了
    马可 说:
     刚试了一下第1个问题,加上top percent就行 
    马可 说:
    发现好多超难问题都是你搞定的 
    马可 说:
    想不服都难
    j9988 说:
    我中午没机器测,晚上才有。不过我想象它的处理机制。因为我常为一个语句的效率测相当长时间。
    马可 说:
    这种问题看来只能以后注意点 
    j9988 说:
    特别有两表组合还要当子查询且列是:a.field+B.field时还要排序时才会
    j9988 说:
    其它情况不会。
    j9988 说:
    比如刚才的如果是order by A.id,B.id就不会。但order by A.id+B.id就会。
    马可 说:
    确实如此
      

  18.   

    要是有人恶意灌水怎么办?服务器受得了吗?csdn的安全性还是处理得不错,很多地方都有限制,比如不能疯狂搜索,不能连续回复等。
      

  19.   

    再测试几个:
    1:ok
    declare @s varchar(8000)
    set @s=''
    select @s=@s+s from (
    select a.id as id1,b.id as id2, rtrim(a.id+B.id)+',' as s
    from 
    (select id=0 union all select 1 union all select 2) A,
    (select id=0 union all select 12 union all select 24) b
    ) s 
    order by id1,id2
    print @s2:不对
    declare @s varchar(8000)
    set @s=''
    select @s=@s+s from (
    select a.id as id1,b.id as id2, rtrim(a.id+B.id)+',' as s
    from 
    (select id=0 union all select 1 union all select 2) A,
    (select id=0 union all select 12 union all select 24) b
    ) s 
    order by id1,id2,s
    print @s3:不对
    declare @s varchar(8000)
    set @s=''
    select @s=@s+s from (
    select a.id as id1,b.id as id2, rtrim(a.id+B.id)+',' as s
    from 
    (select id=0 union all select 1 union all select 2) A,
    (select id=0 union all select 12 union all select 24) b
    ) s 
    order by id1+id2
    print @s
      

  20.   

    txlicenhe(马可) :
    你怎么突然出现了,明摆着妨碍我讲话吗,看来有几颗星星的都不是好人!
    不是斑竹也这样!ps:受 j老师的启发也试了下第一个问题,好玩。
      

  21.   

    哦,我刚洗过手的,握一下无妨,给个面子嘛。
    无上光荣,高兴ing...
      

  22.   

    wzh1215(懒猫) ,REALGZ:
    宝马撞人白撞,你们没意见,我多上几贴你们就吵。
      

  23.   

    Top 100  percent
    记下了,下次有这种问题就用来和星星们抢楼。
      

  24.   

    j9988(j9988):我都上新浪挤服务器了,在CSDN火气不够大,不好玩。
      

  25.   

    txlicenhe(马可) :握完我就知道上当了:谁说你洗了手,键盘上细菌最多了。
      

  26.   

    To: j9988(j9988) 
    你用宝马撞我当然有意见,不过用钱砸我我就不敢吭气了!
      

  27.   

    各位n星,n角大侠:太长,我根本没看,自知也看不懂。灌水吧:我12月开始学sql,将近04年才有勇气虎口拔牙——厚着脸皮跟诸位大虾抢分(难、太难...),不过,确实有乐趣!你们继续,祝我们新年新突破-----事业、感情......
      

  28.   

    我晕,我灌水前还是
    realgz(realgz) ( ) 信誉:105  2004-01-08 20:57:00  得分:0 
     
     
      楼上 握手先!
      
     
    怎么...
    斑竹灌水也牛比!
      

  29.   

    果然内部机制是游标的机制。加上DISTINCT也可以。只要子查询中有:order by ,top,distinct三个关键字中的一个就行。当然order by 在本题子查询内部不能用。
    准一个游标机制。
      

  30.   

    程序太繁琐,看不过来哦!但是出错的方向很明显!select ... from a,b where a.x=b.x 

    select ... from a inner join b on a.x=b.x是根本不同的查询。我从来不用后者含混的关联操作。如果用,就请搞清楚它的查询规划生成的具体查询方法——与内连接本来就是不同的!看起来逻辑相同,其实含混的关联操作往往先将很多冗余数据关联起来,然后再剔除他们,很自然,与先选择记录后关联的规范的写法相比会生成很多导致运行失败的记录。
    最后那个问题,在子查询中不能使用order by,除非使用了 top ... 的查询形式,这在SQL Server手册中是白纸黑字写明了的。