列出表中的所有负数和最小正数

时间:2014-11-06 09:18:02

标签: sql-server

这是一个示例表,我希望得到每个id的所有负数和最小正数(包括0)

    declare  @tbl table(id INT, value decimal, someData varchar(10))

    insert into @tbl
    values(1,-3,123),(1,-2,234),(1,-1,345),(1,3,456),(1,4,567),(2,-4,678),(2,-2,789),(2,1,890),(2,2,135),(3,-5,246),(3,10,357)

    select * from @tbl where value < 0 union 
    select id, min(value),someData from @tbl WHERE value > 0 group by id,somedata

我试图通过分离缺点和优点找到解决方案。但由于某些数据,我无法按需要分组。

期望的结果是:

1   -3  123
1   -2  234
1   -1  345
1   3   456
2   -4  678
2   -2  789
2   1   890
3   -5  246
3   10  357

这也是一个漫长的工作查询,所以我不想做双选。是否可以在一个选择中进行?

4 个答案:

答案 0 :(得分:1)

这应该有效:

;With separated as (
    select *,ROW_NUMBER() OVER (PARTITION BY SIGN(value),id ORDER BY value) as rn
    from @tbl
)
select * from separated where SIGN(value) < 0 or rn=1

如果value为0,您还没有说明会发生什么情况,所以如果您的数据包含某些内容,则上述内容可能正确也可能不正确。

SIGN在SQL Server中是一个很少使用但偶尔有用的函数,返回-1,0或+1,并允许我们轻松地将数组分成3组。

答案 1 :(得分:0)

使用Window function你可以得到最小值。并使用UNION来组合结果。试试这个..

;WITH CTE
     AS (SELECT Row_number() OVER (PARTITION BY ID ORDER BY value) RN, *
         FROM   @tbl
         WHERE  value > 0) 
SELECT *
FROM   @tbl
WHERE  value < 0
UNION ALL
SELECT ID,value,someData
FROM   CTE
WHERE  RN = 1

答案 2 :(得分:0)

使用联合来组合条件可能是最容易的。但是要选择具有最小正值的行需要子查询,并假设ID是唯一标识符:

select id,value,somdata from @tbl where value < 0
union
select id,value,somdata from @tbl
where value = (select min(value) from @tbl where value > 0)

(这不会包含零值的行,但问题并不是说它们应该落在哪一侧。)

答案 3 :(得分:0)

使用OR where子句将其作为单个选择进行攻击,使用子查询获取最小正数:

select * from @tbl
where value < 0
or value = (
    select min(value)
    from @tbl
    where value > 0)