在SQL中选择特定的不同列

时间:2017-08-31 14:14:00

标签: sql sql-server

我正在尝试创建一个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的方式做点什么, 但如果所有列都相同,则只会删除重复项。

3 个答案:

答案 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编辑了他的帖子,其中包含了一个没有聚合的版本......