从表中获取所有月份中特定列具有非空值的记录

时间:2016-04-06 09:55:59

标签: sql-server

我有一张桌子:

Project_Id  Period  Value

123 Jan-15  0
123 Feb-15  34
123 Mar-15  78
123 Apr-15  56
456 Jan-15  0
456 Feb-15  0
456 Mar-15  0
456 Apr-15  0
789 Jan-15  45
789 Feb-15  4
789 Mar-15  18
789 Apr-15  26

我只需要在所有月份中没有0表示Value字段时检索项目数据,如:

Project_Id  Period  Value
123 Jan-15  0
123 Feb-15  34
123 Mar-15  78
123 Apr-15  56
789 Jan-15  45
789 Feb-15  4
789 Mar-15  18
789 Apr-15  26

项目编号456不应出现在我的结果中,因为对于该特定项目,所有月份的值都为0

有人可以帮我查询吗?

4 个答案:

答案 0 :(得分:1)

使用SUMCOUNT确定0 Value的数量:

SELECT *
FROM tbl 
WHERE project_id IN(
    SELECT project_id
    FROM tbl
    GROUP BY project_id
    HAVING SUM(CASE WHEN Value = 0 THEN 1 ELSE 0 END) <> COUNT(*)
)

SQL Fiddle

另一种解决方案是使用EXISTS

SELECT *
FROM tbl t1
WHERE EXISTS(
    SELECT 1 FROM tbl t2 WHERE t2.project_id = t1.project_id AND t2.Value > 0
)

SQL Fiddle

答案 1 :(得分:0)

内部选择会获得至少一个project_id不是value的所有0

select * from your_table
where project_id in 
(
  select project_id
  from your_table
  group by project_id
  having sum(case when value <> 0 then 1 else 0 end) > 0
)

答案 2 :(得分:0)

一些测试数据但想法保持不变

create table #test123
   (
   pid     int,
   value int
   ) 


   insert into #test123
   select 1,0
   union all
   select 1,1
   union  all
   select 2,0
   union all
   select 2,0
   union all
   select 3,2


   select * from #test123 t2 where exists (select 1 from #test123 t1 
                                                    where t1.pid=t2.pid
                                                         group by pid
                                                      having sum(value)>0
                                            )

答案 3 :(得分:0)

为了提高性能,我不想进行连接来检查重复值:

;WITH CTE as
(
  SELECT 
    Project_Id,
    Period,
    Value,
    max(abs(value)) over (Partition by Period) value
  FROM YourTable
)
SELECT 
  Project_Id,
  Period,
  Value
FROM CTE
WHERE value > 0

*使用abs检查负值。如果所有值都是正数,则可以省略abs。