group by 语句请教!

ming_Y 2009-09-07 10:10:22
请教各位高手,在select 中使用了聚合函数,但我又不想把所有字段放在group by 语句中进行分组,怎么来解决这些字段不存在于聚合函数中的问题.THANK YOU!
...全文
221 24 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
jayqean 2009-09-07
  • 打赏
  • 举报
回复
好像楼上各位都没有理解楼主的意思呀!
select 后面跟了聚合函数 没有使用聚合函数的列必须出现在group by 后面呀
king269 2009-09-07
  • 打赏
  • 举报
回复
路过,学习了
dawugui 2009-09-07
  • 打赏
  • 举报
回复
select a.name,min(a.order) order ,sum(a.number),b.style,c.code
from a , b , c
where a.id=b.id1 and b.rkey=c.parent
group by a.name,b.style,c.code

select a.name,max(a.order) order ,sum(a.number),b.style,c.code
from a , b , c
where a.id=b.id1 and b.rkey=c.parent
group by a.name,b.style,c.code
haitao00244 2009-09-07
  • 打赏
  • 举报
回复
首先要注意分组查询的key有先后顺序,
group by a.name,a.order,b.style,c.code
再就是要分清主表、次表。
你可以去掉inner join 和left join 用where条件来替代一下 试试看
ming_Y 2009-09-07
  • 打赏
  • 举报
回复
呵呵,就是想保留c.code了.
xuejiecn 2009-09-07
  • 打赏
  • 举报
回复
把c.code去掉不查。不知道你这样做的初衷。
ming_Y 2009-09-07
  • 打赏
  • 举报
回复
各位高手请再次赐教下!
ming_Y 2009-09-07
  • 打赏
  • 举报
回复
我简单举个例子:
A表: id name order number
1 LI 001123 10000
2 LIU 001225 12000
3 ZHENG 001366 20000
4 TU 001850 5000
5 wang 001866 18000
6 LIU 001910 10000
7 TU 001950 50000
B表: id1 style key
1 B100 1
2 B101 2
3 B102 3
4 B103 4
5 B110 5
6 B120 6
7 B200 7
C表: parent code
1 0001
1 0002
2 0006
3 0008
4 0009
4 0010
5 0013
6 0018
7 0020
A表id=B表id1,B表key=C表parent;
我的语句:select a.name,a.order,sum(a.number),b.style,c.code from a inner join
b on a.id=b.id1 left join c on b.rkey=c.parent
group by a.order,a.name,b.style,c.code
实际我只想按a.name分组,只有5条记录.而现在这个查询语句为7条记录.
fwacky 2009-09-07
  • 打赏
  • 举报
回复
可以利用 子查询

select *,count=(select count(1) from table where id = A.id and value > A.value ) from tablename A
翼帆 2009-09-07
  • 打赏
  • 举报
回复
可使用over子句,如
USE AdventureWorks;
GO
SELECT SalesOrderID, ProductID, OrderQty
,SUM(OrderQty) OVER(PARTITION BY SalesOrderID) AS 'Total'
,CAST(1. * OrderQty / SUM(OrderQty) OVER(PARTITION BY SalesOrderID)
*100 AS DECIMAL(5,2))AS 'Percent by ProductID'
FROM Sales.SalesOrderDetail
WHERE SalesOrderID IN(43659,43664);
GO

详见:
http://msdn.microsoft.com/zh-cn/library/ms189461.aspx
zhangjiang264 2009-09-07
  • 打赏
  • 举报
回复
顶 5,6楼,都是牛人。。
学习了
usher_gml 2009-09-07
  • 打赏
  • 举报
回复
方法比较多.还得看具体情况..
华夏小卒 2009-09-07
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 ming_y 的回复:]
        假如我这个查询关联好几个表,用简单not exists可能就不好解决了吧?
[/Quote]

先关联,再group by

所以要具体情况,具体分析
ming_Y 2009-09-07
  • 打赏
  • 举报
回复
假如我这个查询关联好几个表,用简单not exists可能就不好解决了吧?
dawugui 2009-09-07
  • 打赏
  • 举报
回复

--按某一字段分组取最大(小)值所在行的数据
--(爱新觉罗.毓华(十八年风雨,守得冰山雪莲花开) 2007-10-23于浙江杭州)
/*
数据如下:
name val memo
a 2 a2(a的第二个值)
a 1 a1--a的第一个值
a 3 a3:a的第三个值
b 1 b1--b的第一个值
b 3 b3:b的第三个值
b 2 b2b2b2b2
b 4 b4b4
b 5 b5b5b5b5b5
*/
--创建表并插入数据:
create table tb(name varchar(10),val int,memo varchar(20))
insert into tb values('a', 2, 'a2(a的第二个值)')
insert into tb values('a', 1, 'a1--a的第一个值')
insert into tb values('a', 3, 'a3:a的第三个值')
insert into tb values('b', 1, 'b1--b的第一个值')
insert into tb values('b', 3, 'b3:b的第三个值')
insert into tb values('b', 2, 'b2b2b2b2')
insert into tb values('b', 4, 'b4b4')
insert into tb values('b', 5, 'b5b5b5b5b5')
go

--一、按name分组取val最大的值所在行的数据。
--方法1:
select a.* from tb a where val = (select max(val) from tb where name = a.name) order by a.name
--方法2:
select a.* from tb a where not exists(select 1 from tb where name = a.name and val > a.val)
--方法3:
select a.* from tb a,(select name,max(val) val from tb group by name) b where a.name = b.name and a.val = b.val order by a.name
--方法4:
select a.* from tb a inner join (select name , max(val) val from tb group by name) b on a.name = b.name and a.val = b.val order by a.name
--方法5
select a.* from tb a where 1 > (select count(*) from tb where name = a.name and val > a.val ) order by a.name
/*
name val memo
---------- ----------- --------------------
a 3 a3:a的第三个值
b 5 b5b5b5b5b5
*/

--二、按name分组取val最小的值所在行的数据。
--方法1:
select a.* from tb a where val = (select min(val) from tb where name = a.name) order by a.name
--方法2:
select a.* from tb a where not exists(select 1 from tb where name = a.name and val < a.val)
--方法3:
select a.* from tb a,(select name,min(val) val from tb group by name) b where a.name = b.name and a.val = b.val order by a.name
--方法4:
select a.* from tb a inner join (select name , min(val) val from tb group by name) b on a.name = b.name and a.val = b.val order by a.name
--方法5
select a.* from tb a where 1 > (select count(*) from tb where name = a.name and val < a.val) order by a.name
/*
name val memo
---------- ----------- --------------------
a 1 a1--a的第一个值
b 1 b1--b的第一个值
*/

--三、按name分组取第一次出现的行所在的数据。
select a.* from tb a where val = (select top 1 val from tb where name = a.name) order by a.name
/*
name val memo
---------- ----------- --------------------
a 2 a2(a的第二个值)
b 1 b1--b的第一个值
*/

--四、按name分组随机取一条数据。
select a.* from tb a where val = (select top 1 val from tb where name = a.name order by newid()) order by a.name
/*
name val memo
---------- ----------- --------------------
a 1 a1--a的第一个值
b 5 b5b5b5b5b5
*/

--五、按name分组取最小的两个(N个)val
select a.* from tb a where 2 > (select count(*) from tb where name = a.name and val < a.val ) order by a.name,a.val
select a.* from tb a where val in (select top 2 val from tb where name=a.name order by val) order by a.name,a.val
select a.* from tb a where exists (select count(*) from tb where name = a.name and val < a.val having Count(*) < 2) order by a.name,a.val
/*
name val memo
---------- ----------- --------------------
a 1 a1--a的第一个值
a 2 a2(a的第二个值)
b 1 b1--b的第一个值
b 2 b2b2b2b2
*/

--六、按name分组取最大的两个(N个)val
select a.* from tb a where 2 > (select count(*) from tb where name = a.name and val > a.val ) order by a.name,a.val
select a.* from tb a where val in (select top 2 val from tb where name=a.name order by val desc) order by a.name,a.val
select a.* from tb a where exists (select count(*) from tb where name = a.name and val > a.val having Count(*) < 2) order by a.name , a.val
/*
name val memo
---------- ----------- --------------------
a 2 a2(a的第二个值)
a 3 a3:a的第三个值
b 4 b4b4
b 5 b5b5b5b5b5
*/
--七,如果整行数据有重复,所有的列都相同。
/*
数据如下:
name val memo
a 2 a2(a的第二个值)
a 1 a1--a的第一个值
a 1 a1--a的第一个值
a 3 a3:a的第三个值
a 3 a3:a的第三个值
b 1 b1--b的第一个值
b 3 b3:b的第三个值
b 2 b2b2b2b2
b 4 b4b4
b 5 b5b5b5b5b5
*/
--在sql server 2000中只能用一个临时表来解决,生成一个自增列,先对val取最大或最小,然后再通过自增列来取数据。
--创建表并插入数据:
create table tb(name varchar(10),val int,memo varchar(20))
insert into tb values('a', 2, 'a2(a的第二个值)')
insert into tb values('a', 1, 'a1--a的第一个值')
insert into tb values('a', 1, 'a1--a的第一个值')
insert into tb values('a', 3, 'a3:a的第三个值')
insert into tb values('a', 3, 'a3:a的第三个值')
insert into tb values('b', 1, 'b1--b的第一个值')
insert into tb values('b', 3, 'b3:b的第三个值')
insert into tb values('b', 2, 'b2b2b2b2')
insert into tb values('b', 4, 'b4b4')
insert into tb values('b', 5, 'b5b5b5b5b5')
go

select * , px = identity(int,1,1) into tmp from tb

select m.name,m.val,m.memo from
(
select t.* from tmp t where val = (select min(val) from tmp where name = t.name)
) m where px = (select min(px) from
(
select t.* from tmp t where val = (select min(val) from tmp where name = t.name)
) n where n.name = m.name)

drop table tb,tmp

/*
name val memo
---------- ----------- --------------------
a 1 a1--a的第一个值
b 1 b1--b的第一个值

(2 行受影响)
*/
--在sql server 2005中可以使用row_number函数,不需要使用临时表。
--创建表并插入数据:
create table tb(name varchar(10),val int,memo varchar(20))
insert into tb values('a', 2, 'a2(a的第二个值)')
insert into tb values('a', 1, 'a1--a的第一个值')
insert into tb values('a', 1, 'a1--a的第一个值')
insert into tb values('a', 3, 'a3:a的第三个值')
insert into tb values('a', 3, 'a3:a的第三个值')
insert into tb values('b', 1, 'b1--b的第一个值')
insert into tb values('b', 3, 'b3:b的第三个值')
insert into tb values('b', 2, 'b2b2b2b2')
insert into tb values('b', 4, 'b4b4')
insert into tb values('b', 5, 'b5b5b5b5b5')
go

select m.name,m.val,m.memo from
(
select * , px = row_number() over(order by name , val) from tb
) m where px = (select min(px) from
(
select * , px = row_number() over(order by name , val) from tb
) n where n.name = m.name)

drop table tb

/*
name val memo
---------- ----------- --------------------
a 1 a1--a的第一个值
b 1 b1--b的第一个值

(2 行受影响)
*/
华夏小卒 2009-09-07
  • 打赏
  • 举报
回复

--I、Name相同ID最小的记录(推荐用1,2,3),方法3在SQl05时,效率高于1、2
方法1:
Select * from #T a where not exists(select 1 from #T where Name=a.Name and ID<a.ID)

方法2:
select a.* from #T a join (select min(ID)ID,Name from #T group by Name) b on a.Name=b.Name and a.ID=b.ID

方法3:
select * from #T a where ID=(select min(ID) from #T where Name=a.Name)

方法4:
select a.* from #T a join #T b on a.Name=b.Name and a.ID>=b.ID group by a.ID,a.Name,a.Memo having count(1)=1

方法5:
select * from #T a group by ID,Name,Memo having ID=(select min(ID)from #T where Name=a.Name)

方法6:
select * from #T a where (select count(1) from #T where Name=a.Name and ID<a.ID)=0

方法7:
select * from #T a where ID=(select top 1 ID from #T where Name=a.name order by ID)

方法8:
select * from #T a where ID!>all(select ID from #T where Name=a.Name)

方法9(注:ID为唯一时可用):
select * from #T a where ID in(select min(ID) from #T group by Name)

ming_Y 2009-09-07
  • 打赏
  • 举报
回复
呵呵,我只是想到这个问题,没数据.你能否举个简单的例子来说明如何处理这个问题的!
sdhdy 2009-09-07
  • 打赏
  • 举报
回复
--可以考虑用not exists实现。
--col1为你的分组字段,依次类推。
--如:
select * from tb a
where not exists(select 1 from tb where col1=a.col1 and col2>a.col2)
lihan6415151528 2009-09-07
  • 打赏
  • 举报
回复
请给出测试数据,计算方法和正确结果.
dawugui 2009-09-07
  • 打赏
  • 举报
回复
请给出测试数据,计算方法和正确结果.
加载更多回复(4)

34,837

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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