如何计算每个 ID 的正数和负数?

How to get count of postitive and negative numbers per ID?

我想计算每个 ID 的负值和正值。

Sample Fiddle

ID=1 has 2 positive and 0 negative transactions. etc.

 with trans_detail as 
 (
 select 1 as trans_id, 100 as trans_amount  from dual union all
 select 1 as trans_id, 200 as trans_amount  from dual union all
 select 2 as trans_id, -100 as trans_amount  from dual union all
 select 2 as trans_id, -300 as trans_amount  from dual union all
 select 3 as trans_id, 400 as trans_amount   from dual union all
 select 3 as trans_id, -500 as trans_amount  from dual
 )

 select trans_id,
       count(*) over (partition by trans_id) as pos_count,
       count(*) over (partition by trans_id) as neg_count        
from trans_detail
where trans_amount > 0
UNION
select trans_id,
       count(*) over (partition by trans_id) as pos_count,
       count(*) over (partition by trans_id) as neg_count        
from trans_detail
where trans_amount < 0;

期望的结果:

 ID   POS_COUNT   NEG_COUNT
---- ----------- -----------
 1    2           0 
 2    0           2
 3    1           1
select trans_id, 
nvl(sum(case when trans_amount < 0 then 1 end),0) as neg,
nvl(sum(case when trans_amount > 0 then 1 end),0) as pos
from trans_detail
group by trans_id

SQL Fiddle: http://sqlfiddle.com/#!4/db410/15

每次看到正数或负数时数 1,然后求和。

select trans_id,
sum(case when trans_amount >=0 then 1 else 0 end) as pos_amt,
sum(case when trans_amount < 0 then 1 else 0 end) as neg_amt
from trans_detail
group by trans_id

http://sqlfiddle.com/#!4/db410/12

您可以使用条件计数:

with trans_detail as 
 (
 select 1 as trans_id, 100 as trans_amount  from dual union all
 select 1 as trans_id, 200 as trans_amount  from dual union all
 select 2 as trans_id, -100 as trans_amount  from dual union all
 select 2 as trans_id, -300 as trans_amount  from dual union all
 select 3 as trans_id, 400 as trans_amount   from dual union all
 select 3 as trans_id, -500 as trans_amount  from dual
 )
select trans_id,
       count(case when trans_amount >= 0 then trans_id end) as pos_count,
       count(case when trans_amount < 0 then trans_id end) as neg_count        
from trans_detail
group by trans_id
order by trans_id;

  TRANS_ID  POS_COUNT  NEG_COUNT
---------- ---------- ----------
         1          2          0
         2          0          2
         3          1          1

Count 忽略空值,因此每个案例的隐式空值 'else' 意味着不计算这些行。如果你愿意,你可以添加 else null 但这只会让它更长一点。 (我已经将零作为 'positive' 包含在内,但您可能希望在您的问题中完全忽略它;在这种情况下,只需恢复为 > 0)。

SQL Fiddle

您也可以在案例或解码中使用 the sign function

select trans_id,
       count(decode(sign(trans_amount), 1, trans_id)) as pos_count,
       count(decode(sign(trans_amount), -1, trans_id)) as neg_count        
from trans_detail
group by trans_id
order by trans_id;

SQL Fiddle;这会忽略零,但如果需要,您可以将其包含在任一解码器中。

试试这个

select trans_id,
       Sum(case when trans_amount>=0 then 1 else 0 end) as pos_count,
       Sum(case when trans_amount<0 then 1 else 0 end) as neg_count,
from trans_detail
group by trans_id