group by 出现一个奇怪的问题

cwj731 2013-12-16 10:17:43
union三个数据集后group by时其中一个数据集的部分数据没有group,而如果我在每个数据集后加入一标志列ftype则结果正确。这是为什么呢?


代码如下:
select p.billno,p.fitemid ,sum(p.fqty) as fqty from (
select '1' as ftype,t.fbillno as billno,t1.fitemid,sum(t1.fqty) as fqty from icstockbill t left join icstockbillentry t1 on t1.finterid=t.finterid
inner join (select distinct left(fbillno,CHARINDEX('退',fbillno)-1) as fbillno from SEOutStock where fbillno like '%退%' and fdate>='2008-01-01' and fdate<='2013-12-31' and fcancellation=0 and fstatus>=1 group by fbillno) o on o.fbillno = t.fbillno
where t.fdate>='2008-01-01' and t.fdate<='2013-12-31' and ftrantype=21 and frob=1 and fcancellation=0 and fstatus>=1 group by t.fbillno,t1.fitemid
union
select '2' as ftype,left(tp.fbillno,CHARINDEX('退',tp.fbillno)-1) as billno,tp1.fitemid,sum(tp1.fqty) as fqty from icstockbill tp left join icstockbillentry tp1 on tp1.finterid=tp.finterid
where tp.fbillno like '%退%' and tp.fdate>='2008-01-01' and tp.fdate<='2013-12-31' and ftrantype=21 and fcancellation=0 and fstatus>=1 group by tp.fbillno,tp1.fitemid
union
select '3' as ftype,tt1.fsourcebillno as billno,fitemid,sum(fqty) as fqty from icstockbill tt left join icstockbillentry tt1 on tt1.finterid=tt.finterid
inner join (select distinct left(fbillno,CHARINDEX('退',fbillno)-1) as fbillno from SEOutStock where fbillno like '%退%' and fdate>='2008-01-01' and fdate<='2013-12-31' and fcancellation=0 and fstatus>=1 group by fbillno) o1 on o1.fbillno = tt1.fsourcebillno
where tt.fdate>='2008-01-01' and tt.fdate<='2013-12-31' and ftrantype=21 and frob=-1 and fcancellation=0 and fstatus>=1 group by tt1.fsourcebillno,tt1.fitemid
) p group by p.billno,p.fitemid
...全文
136 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
發糞塗牆 2013-12-16
  • 打赏
  • 举报
回复
那就是Union 去重了导致数据“少了”
cwj731 2013-12-16
  • 打赏
  • 举报
回复
啊,感谢!的确是因为没加all引起的,我真笨。列太少造成有些记录是相同的,省略了。哈哈!
Yole 2013-12-16
  • 打赏
  • 举报
回复
看半天没看出啥问题呢?
發糞塗牆 2013-12-16
  • 打赏
  • 举报
回复
那是眼睛,800度,有点深
引用 13 楼 js_szy 的回复:
[quote=引用 11 楼 DBA_Huangzj 的回复:] 我擦,看着标题就写错了,只有最后一个order by》。。。 [quote=引用 10 楼 js_szy 的回复:] [quote=引用 9 楼 DBA_Huangzj 的回复:] 去掉第一个order by就没问题
CREATE TABLE #t (id int)
SELECT * FROM #t
--ORDER BY id
UNION ALL 
SELECT * FROM #t
ORDER BY id 
跟order by 有什么关系 而且union all 的哪个子句都可以加group by 。为什么说最后一个才能加呢。 order by是最后一个才能加。 而且楼主这语句跟下面这个类似。是肯定能分组的。不能分组的话,问题应该出在其他地方
select id,sum(num) from (
select id,sum(num) as num from ta group by id
union all
select id,sum(num) from tb group by id
)p
group by id
[/quote][/quote] 两猫眼睁那么大,光看凶器了吧[/quote]
华夏小卒 2013-12-16
  • 打赏
  • 举报
回复
引用 11 楼 DBA_Huangzj 的回复:
我擦,看着标题就写错了,只有最后一个order by》。。。 [quote=引用 10 楼 js_szy 的回复:] [quote=引用 9 楼 DBA_Huangzj 的回复:] 去掉第一个order by就没问题
CREATE TABLE #t (id int)
SELECT * FROM #t
--ORDER BY id
UNION ALL 
SELECT * FROM #t
ORDER BY id 
跟order by 有什么关系 而且union all 的哪个子句都可以加group by 。为什么说最后一个才能加呢。 order by是最后一个才能加。 而且楼主这语句跟下面这个类似。是肯定能分组的。不能分组的话,问题应该出在其他地方
select id,sum(num) from (
select id,sum(num) as num from ta group by id
union all
select id,sum(num) from tb group by id
)p
group by id
[/quote][/quote] 两猫眼睁那么大,光看凶器了吧
發糞塗牆 2013-12-16
  • 打赏
  • 举报
回复
不过我说写死标识列的方法应该还是可以的
發糞塗牆 2013-12-16
  • 打赏
  • 举报
回复
我擦,看着标题就写错了,只有最后一个order by》。。。
引用 10 楼 js_szy 的回复:
[quote=引用 9 楼 DBA_Huangzj 的回复:] 去掉第一个order by就没问题
CREATE TABLE #t (id int)
SELECT * FROM #t
--ORDER BY id
UNION ALL 
SELECT * FROM #t
ORDER BY id 
跟order by 有什么关系 而且union all 的哪个子句都可以加group by 。为什么说最后一个才能加呢。 order by是最后一个才能加。 而且楼主这语句跟下面这个类似。是肯定能分组的。不能分组的话,问题应该出在其他地方
select id,sum(num) from (
select id,sum(num) as num from ta group by id
union all
select id,sum(num) from tb group by id
)p
group by id
[/quote]
华夏小卒 2013-12-16
  • 打赏
  • 举报
回复
引用 9 楼 DBA_Huangzj 的回复:
去掉第一个order by就没问题
CREATE TABLE #t (id int)
SELECT * FROM #t
--ORDER BY id
UNION ALL 
SELECT * FROM #t
ORDER BY id 
跟order by 有什么关系 而且union all 的哪个子句都可以加group by 。为什么说最后一个才能加呢。 order by是最后一个才能加。 而且楼主这语句跟下面这个类似。是肯定能分组的。不能分组的话,问题应该出在其他地方
select id,sum(num) from (
select id,sum(num) as num from ta group by id
union all
select id,sum(num) from tb group by id
)p
group by id
發糞塗牆 2013-12-16
  • 打赏
  • 举报
回复
去掉第一个order by就没问题
CREATE TABLE #t (id int)
SELECT * FROM #t
--ORDER BY id
UNION ALL 
SELECT * FROM #t
ORDER BY id 
發糞塗牆 2013-12-16
  • 打赏
  • 举报
回复
CREATE TABLE #t (id int)
SELECT * FROM #t
ORDER BY id
UNION ALL 
SELECT * FROM #t
ORDER BY id 
/*
Msg 156, Level 15, State 1, Line 4
Incorrect syntax near the keyword 'UNION'.
*/
  • 打赏
  • 举报
回复
好像都可以加的,不管是union all 还是union,都可以加group by的。
發糞塗牆 2013-12-16
  • 打赏
  • 举报
回复
引用 4 楼 js_szy 的回复:
[quote=引用 1 楼 DBA_Huangzj 的回复:] union all里面只能最后一个加group by,如果是2005及以上版本,可以每个查询加上一个标识列,比如用row_number来生成,然后order by的时候排序
有这样的规则? union all里面只能最后一个加group by[/quote]你可以试一下嘛
  • 打赏
  • 举报
回复
union 会去重,而union all不会去重的。 你可以考虑把union 改成union all,我把你的ftype列去掉了,你再试试:
select p.billno,p.fitemid ,sum(p.fqty) as fqty from (

select t.fbillno as billno,t1.fitemid,sum(t1.fqty) as fqty from icstockbill t left join icstockbillentry t1 on t1.finterid=t.finterid 
inner join (select distinct left(fbillno,CHARINDEX('退',fbillno)-1) as fbillno from SEOutStock where fbillno like '%退%' and fdate>='2008-01-01' and fdate<='2013-12-31' and fcancellation=0  and fstatus>=1 group by fbillno) o on o.fbillno = t.fbillno
where t.fdate>='2008-01-01' and t.fdate<='2013-12-31' and ftrantype=21 and frob=1 and fcancellation=0 and fstatus>=1 
group by t.fbillno,t1.fitemid

union all

select left(tp.fbillno,CHARINDEX('退',tp.fbillno)-1) as billno,tp1.fitemid,sum(tp1.fqty) as fqty from icstockbill tp left join icstockbillentry tp1 on tp1.finterid=tp.finterid 
where tp.fbillno like '%退%' and tp.fdate>='2008-01-01' and tp.fdate<='2013-12-31' and ftrantype=21  and fcancellation=0 and fstatus>=1 
group by tp.fbillno,tp1.fitemid

union all

select tt1.fsourcebillno as billno,fitemid,sum(fqty) as fqty  from icstockbill tt left join icstockbillentry tt1 on tt1.finterid=tt.finterid 
inner join (select distinct left(fbillno,CHARINDEX('退',fbillno)-1) as fbillno from SEOutStock where fbillno like '%退%' and fdate>='2008-01-01' and fdate<='2013-12-31' and fcancellation=0  and fstatus>=1 group by fbillno) o1 on o1.fbillno = tt1.fsourcebillno
where tt.fdate>='2008-01-01' and tt.fdate<='2013-12-31' and ftrantype=21 and frob=-1 and fcancellation=0 and fstatus>=1 
group by tt1.fsourcebillno,tt1.fitemid 
 ) p     
 group by p.billno,p.fitemid
华夏小卒 2013-12-16
  • 打赏
  • 举报
回复
引用 1 楼 DBA_Huangzj 的回复:
union all里面只能最后一个加group by,如果是2005及以上版本,可以每个查询加上一个标识列,比如用row_number来生成,然后order by的时候排序
有这样的规则? union all里面只能最后一个加group by
华夏小卒 2013-12-16
  • 打赏
  • 举报
回复
应该不会,问题在其他地方
發糞塗牆 2013-12-16
  • 打赏
  • 举报
回复
或者写死标识列,比如:
select *
from (
select *,1 as orderid
from tb
union all 
select *,2 
from tb2
union all 
select *,3
from tb3)x
order by orderid
發糞塗牆 2013-12-16
  • 打赏
  • 举报
回复
union all里面只能最后一个加group by,如果是2005及以上版本,可以每个查询加上一个标识列,比如用row_number来生成,然后order by的时候排序

22,199

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧