首页 新闻 会员 周边 捐助

大家看怎么用最短的SQL语句写出来

0
悬赏园豆:5 [已解决问题] 解决于 2014-03-31 15:21

查询出每个会员消费金额最大 并按时间排序 上面是查询结果,,, 分组我已经用了 但是 时间这个地方不好弄

90后1场梦的主页 90后1场梦 | 菜鸟二级 | 园豆:244
提问于:2014-03-28 15:18
< >
分享
最佳答案
0
CREATE TABLE dbo.PayRecord (
PID  nvarchar(20) ,
PMONEY MONEY NOT NULL,
PTIME datetime NOT NULL
);
GO
--插入数据
INSERT into PayRecord(PID, PMONEY,PTIME) values
('001', 200,'2013-10-23'),
('001', 500,'2013-2-23'),
('001', 700,'2013-3-23'),
('002', 900,'2013-5-23'),
('002', 800,'2013-6-2'),
('002', 700,'2013-9-23'),
('002', 600,'2013-10-23'),
('003', 300,'2013-11-23'),
('003', 200,'2013-12-23'),
('003', 500,'2013-9-20'),
('003', 800,'2014-1-1');
GO

select * from PayRecord;
/*
PID    PMONEY    PTIME
001    200.00    2013-10-23 00:00:00.000
001    500.00    2013-02-23 00:00:00.000
001    700.00    2013-03-23 00:00:00.000
002    900.00    2013-05-23 00:00:00.000
002    800.00    2013-06-02 00:00:00.000
002    700.00    2013-09-23 00:00:00.000
002    600.00    2013-10-23 00:00:00.000
003    300.00    2013-11-23 00:00:00.000
003    200.00    2013-12-23 00:00:00.000
003    500.00    2013-09-20 00:00:00.000
003    800.00    2014-01-01 00:00:00.000
*/

Select S.PID, S.PMONEY,S.PTIME,S.RowID
From PayRecord T
inner  Join 
(Select Row_Number() over(Partition By PID Order by PMONEY DESC) As RowID,
PID, PMONEY,PTIME From PayRecord 
) S On T.PID = S.PID AND t.PMONEY=S.PMONEY and T.PTIME=S.PTIME 
Where 1=1 and S.ROWID=1
order by S.PTIME desc;

/*
PID    PMONEY    PTIME    RowID
003    800.00    2014-01-01 00:00:00.000    1
002    900.00    2013-05-23 00:00:00.000    1
001    700.00    2013-03-23 00:00:00.000    1
*/

drop table dbo.PayRecord;
收获园豆:5
邀月 | 高人七级 |园豆:25475 | 2014-03-28 16:45

大神 如果不用 Row_Number() over(Partition By PID Order by PMONEY DESC)  这句  可以有更简单的吗

90后1场梦 | 园豆:244 (菜鸟二级) | 2014-03-28 16:48

@禹、: 你可以把这个表加到临时表中,临时表加一个主键就OK了,我所举的例子中ROWID就是起索引主键作用。

邀月 | 园豆:25475 (高人七级) | 2014-03-28 17:25

@邀月: 这个查询出来的 有弊端吧 数据时间会不会就不准确了

90后1场梦 | 园豆:244 (菜鸟二级) | 2014-03-28 17:25
其他回答(3)
0

select Test.* from Test,(select Id,max([Money]) m from Test group by Id) a where Test.Id=a.Id and Test.Money=a.m order by Test.Time desc

先分组查询最大金额,再根据时间排序。有主键吗,有就更简单了

单恋 | 园豆:678 (小虾三级) | 2014-03-28 16:02

有主键,假如数据有很多很多  你这样写可以吗   其实 我用分组都出来 就是 排序的话有问题,如果在group by里加了 时间 就数据不对了, 不加的话,时间字段也出不来啊

支持(0) 反对(0) 90后1场梦 | 园豆:244 (菜鸟二级) | 2014-03-28 16:06

@禹、: 刚才试了一下,貌似跟主键没什么关系。上面的sql语句,能实现你的需求。把test表换成你自己的表试试嘛。

支持(0) 反对(0) 单恋 | 园豆:678 (小虾三级) | 2014-03-28 16:17

@单恋: 我刚才试了你的语句  有个问题,这个ID不是主键  所以不能用 a.id=b.id 这样数据多出了很多 。假如有主键叫UID 怎么写

支持(0) 反对(0) 90后1场梦 | 园豆:244 (菜鸟二级) | 2014-03-28 16:39

@禹、: 哦。还有这种情况。一个会员,最大消费金额为200,但是消费了多次。就会出来多个结果。这种情况你怎么解决的呢

支持(0) 反对(0) 单恋 | 园豆:678 (小虾三级) | 2014-03-28 16:43

@单恋: 我刚才插入了一个  ID 1 Money 700 Time随意   然后 你的SQL查询出来就是4条

支持(0) 反对(0) 90后1场梦 | 园豆:244 (菜鸟二级) | 2014-03-28 16:46

@禹、: 所以的把这种情况考虑进去。一个会员,最大消费金额为200,但是消费了多次。上面的写法没有考虑这种情况

支持(0) 反对(0) 单恋 | 园豆:678 (小虾三级) | 2014-03-28 16:51

@单恋: 你看下楼下写的  才是对的,  但是 我不想用Row_Number() over(Partition By PID Order by PMONEY DESC)

支持(0) 反对(0) 90后1场梦 | 园豆:244 (菜鸟二级) | 2014-03-28 16:52
0

select id,max(money),min(date)

from table

order by min(date) desc

gropu by id

[秦时明月] | 园豆:738 (小虾三级) | 2014-03-28 17:01

关键字 'group' 附近有语法错误  你这不瞎扯吗

支持(0) 反对(0) 90后1场梦 | 园豆:244 (菜鸟二级) | 2014-03-28 17:03

@禹、: 你自己改成你的表 字段

支持(0) 反对(0) [秦时明月] | 园豆:738 (小虾三级) | 2014-03-28 17:04

@禹、: 

select id,max(money),min(date)

from table

 

gropu by id

order by min(date) desc

支持(0) 反对(0) [秦时明月] | 园豆:738 (小虾三级) | 2014-03-28 17:07

@Moon.Orm塑造Orm经典: 哥  你Min(date) 我也没有让你找最小时间  这样一来 时间不就不准确了吗

支持(0) 反对(0) 90后1场梦 | 园豆:244 (菜鸟二级) | 2014-03-28 17:11

@禹、: 

select id,max(money),date

from table

gropu by id,date

order by date desc

支持(0) 反对(0) [秦时明月] | 园豆:738 (小虾三级) | 2014-03-28 17:18

@Moon.Orm塑造Orm经典: 时间写在group by中  能排序 但不能分组了, 没这么简单吧

支持(0) 反对(0) 90后1场梦 | 园豆:244 (菜鸟二级) | 2014-03-28 17:26

@禹、: 测了?

支持(0) 反对(0) [秦时明月] | 园豆:738 (小虾三级) | 2014-03-28 17:28

@Moon.Orm塑造Orm经典: 你这个就会多出很多数据了  本来242  把时间写在分组里 就1000多了

支持(0) 反对(0) 90后1场梦 | 园豆:244 (菜鸟二级) | 2014-03-28 17:29

@禹、: 

select t1.*,table.date from(

select id,max(money)

from table

gropu by id

) as t1

left join table

on t1.id=table.id

 

 

支持(0) 反对(0) [秦时明月] | 园豆:738 (小虾三级) | 2014-03-28 17:32
0
 1 IF OBJECT_ID('dbo.Test','U') IS NOT NULL
 2 DROP TABLE dbo.Test;
 3 GO
 4 CREATE TABLE Test
 5 (
 6 ID INT NOT NULL ,
 7 [Money] MONEY NOT NULL,
 8 [Time]  DATETIME NOT NULL
 9 )
10 INSERT INTO Test(ID,[Money],[Time])
11 VALUES
12 (001,200.00,'2013-01-01'),
13 (001,500.00,'2013-02-01'),
14 (001,700.00,'2013-01-01'),
15 (002,200.00,'2013-03-01'),
16 (002,900.00,'2013-06-01'),
17 (002,800.00,'2013-04-01'),
18 (002,400.00,'2013-12-01'),
19 (003,500.00,'2013-05-01'),
20 (003,700.00,'2013-12-01'),
21 (003,600.00,'2013-03-01'),
22 (003,300.00,'2013-04-01'),
23 (003,200.00,'2013-05-01')
24 
25 /*CROSS APPLY*/
26 SELECT DISTINCT T.ID,A.[Money],A.[Time]  FROM dbo.Test AS T 
27 CROSS APPLY 
28 (SELECT TOP(1) TE.[Money],TE.[Time],TE.ID 
29 FROM DBO.Test AS TE WHERE TE.ID=T.ID 
30 ORDER BY TE.[Money] DESC) AS A 
31 --1    700.00    2013-01-01 00:00:00.000
32 --2    900.00    2013-06-01 00:00:00.000
33 --3    700.00    2013-12-01 00:00:00.000
34 
35 
36 /*JOIN*/ 
37 SELECT T.ID,T.[Money],T.[Time] FROM Test AS T 
38 JOIN
39 (SELECT ID ,MAX([Money]) AS maxmoney FROM dbo.Test GROUP BY ID) AS D 
40  ON D.maxmoney=T.[Money] 
41  AND D.ID=T.ID ORDER BY  T.[Time]
42  
43 --1    700.00    2013-01-01 00:00:00.000
44 --2    900.00    2013-06-01 00:00:00.000
45 --3    700.00    2013-12-01 00:00:00.000

以上是我的回答,看有啥子帮助没。(表设计不规范噢)

Nicolas.Nick | 园豆:232 (菜鸟二级) | 2014-03-28 17:02

你这个错了  如果  同样两条数据 ID Money  都一样 Money最大  就时间不一样  你的语句就会多出数据

支持(0) 反对(0) 90后1场梦 | 园豆:244 (菜鸟二级) | 2014-03-28 17:07

@禹、: 噢。。你再改改在这基础上,貌似你的设计的表结构不满足2NF样。。用ROW_NUMBER比较简单应该

支持(0) 反对(0) Nicolas.Nick | 园豆:232 (菜鸟二级) | 2014-03-28 17:09

@Nick.S.Huang: 其实 我就想知道, 分组以后怎么排序的问题(排序的字段 不在聚合中)

支持(0) 反对(0) 90后1场梦 | 园豆:244 (菜鸟二级) | 2014-03-28 17:13

@禹、: 如果两条数据据只有 TIME不同,取大的时间,还是小的时间?这个是随机么?如果是随机的话,就可以用CROSS APPLY来解决。

支持(0) 反对(0) Nicolas.Nick | 园豆:232 (菜鸟二级) | 2014-03-28 17:15

@禹、: 如果两条数据据只有 TIME不同,取大的时间,还是小的时间?这个是随机么?如果是随机的话,就可以用CROSS APPLY来解决。

SELECT DISTINCT T.ID,A.[Money],A.[Time]  FROM dbo.Test AS T 
CROSS APPLY 
(SELECT TOP(1) TE.[Money],TE.[Time],TE.ID 
FROM DBO.Test AS TE WHERE TE.ID=T.ID 
ORDER BY TE.[Money] DESC) AS A 

 

 

支持(0) 反对(0) Nicolas.Nick | 园豆:232 (菜鸟二级) | 2014-03-28 17:22
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册