我正在尝试创建一个select语句,以便它在一列上执行特定的不同操作。我试图让它成为每个id中没有多个水果。如果在id下有多个水果,我想在腐烂的水果上只使用1个批准的水果。如果该ID下只有1个水果,请使用它。
SELECT id, fruit, fruitweight, status
FROM myfruits
Raw data from current select
id | fruit | fruitweight | status
1 | apple | .2 | approved
1 | apple | .8 | approved
1 | apple | .1 | rotten
1 | orange | .5 | approved
2 | grape | .1 | rotten
2 | orange | .7 | approved
2 | orange | .5 | approved
如何在约束
之后格式化 id | fruit | fruitweight | status
1 | apple | .2 | approved
1 | orange | .5 | approved
2 | grape | .1 | rotten
2 | orange | .7 | approved
我可以按照select distinct id,fruit,fruitweight,status from myfruits
的方式做点什么,
但如果所有列都相同,则只会删除重复项。
答案 0 :(得分:4)
CTE with aggregate and row_number。
root@ubuntu-linux:~/trafficserver/iocore/net/quic# g++ test.cc -std=c++11^C
root@ubuntu-linux:~/trafficserver/iocore/net/quic# g++ -v
gcc version 4.9.4 (Ubuntu 4.9.4-2ubuntu1~14.04.1)
另一种方法,没有聚合...假设您想要第一个水果重量
declare @YourTable table (id int, fruit varchar(64), fruitweight decimal(2,1),status varchar(64))
insert into @YourTable
values
(1,'apple',0.2,'approved'),
(1,'apple',0.8,'approved'),
(1,'apple',0.1,'rotten'),
(1,'orange',0.5,'approved'),
(2,'grape',0.1,'rotten'),
(2,'orange',0.7,'approved'),
(2,'orange',0.5,'approved')
;with cte as(
select
id
,fruit
,fruitweight = min(fruitweight)
,[status]
,RN = row_number() over (partition by id, fruit order by case when status = 'approved' then 1 else 2 end)
from
@YourTable
group by
id,fruit,status)
select
id
,fruit
,fruitweight
,status
from
cte
where RN = 1
答案 1 :(得分:3)
另一种选择是使用 WITH TIES 子句。
示例强>
Select top 1 with ties *
From YourTable
Order By Row_Number() over (Partition By id,fruit order by status,fruitweight)
答案 2 :(得分:1)
没有聚合的scsimon解决方案的缩短版本。 如果你有SQL Server< 2012年,您将不得不使用案例而不是iif。
select
id
,fruit
,fruitweight
,status
from
(
select
id
,fruit
,fruitweight
,status
,rownum = row_number() over(partition by id, fruit order by iif(status = 'approved', 0, 1), fruitweight desc)
from myfruits
) x
where rownum = 1
编辑:我开始写作之前,scsimon编辑了他的帖子,其中包含了一个没有聚合的版本......