基于单行计算多行的列

时间:2016-11-11 20:41:43

标签: oracle

考虑这些数据:

user    code    score
1       1       50 
1       2       100
2       1       100     
3       2       100 
4       2       50

基本上我想获得每个用户的所有分数,但我想要一个仅基于具有特定代码的行的计算列。

所以:CASE WHEN code = 2 AND score > 50 THEN 'Yes' ELSE 'No'

但我希望计算列忽略1代码。

因此上述数据的结果应为:

user    code    score   pass
1       1       50      Yes
1       2       100     Yes
2       1       100     No
3       2       100     Yes
4       2       50      No

我确定有一些Oracle SQL函数可以对数据进行分区,但我不知道如何。

  • 第1行:是,因为同一个用户在第2行中有100个。
  • 第2行:是的,因为代码2是> 50。
  • 第3行:不,因为它是代码1而且他们没有任何代码2分数。
  • 第4行:是的,因为它是代码2> 50。
  • 第5行:不,因为它的代码2低于51。

根据@ mathguy的回答,我做了这个:

CASE 
    WHEN COUNT(CASE 
        WHEN (sortest_tesc_code = 'A02' AND sortest_test_score >= 23) OR
            (sortest_tesc_code = 'S02' AND sortest_test_score >= 540) OR
            (sortest_tesc_code = 'MPT' AND sortest_test_score >= 60) OR
            (sortest_tesc_code = '66' AND sortest_test_score >= 3) THEN 1 END) OVER (PARTITION BY sortest_pidm) = 0 THEN 'No'
    ELSE 'Yes'
END pass,

现在检查数据,但我认为这是有效的。

3 个答案:

答案 0 :(得分:3)

这是分析功能的工作。当然,user是保留字,因此它不应该是列名。除此之外:

with
     test_data ( usr, code, score ) as (
       select 1, 1,  50 from dual union all
       select 1, 2, 100 from dual union all
       select 2, 1, 100 from dual union all
       select 3, 2, 100 from dual union all
       select 4, 2,  50 from dual
     )
-- end of test data. Solution (SQL query) begins below this line
select usr, code, score,
       case when count(case when code != 1 and score > 50 then 1 end)
                 over (partition by usr) = 0 then 'No' else 'Yes' end as passed
from test_data
;

       USR       CODE      SCORE PASSED
---------- ---------- ---------- ------
         1          1         50 Yes
         1          2        100 Yes
         2          1        100 No 
         3          2        100 Yes
         4          2         50 No 

答案 1 :(得分:1)

仍然做了很多假设......但是这会产生给出的输出..

with cte as (
Select 1 usr,       1 code,       50 score  from dual union all
Select 1,       2,       100 from dual union all
Select 2,       1,       100 from dual union all     
Select 3 ,      2,       100 from dual union all
Select 4  ,     2,       50 from dual )
Select A.*, case when B.usr is null then 'No' else 'Yes' end as pass
from cte A
LEFT JOIN (Select * from cte where code = 2 and score > 50) B
 on A.Usr = B.usr
 order by A.usr, A.code

enter image description here

答案 2 :(得分:0)

with userscore (select user, sum(case WHEN code = 2 AND score > 50 then 1 else 0) s end 
                from my_table group by user)
select m.*, CASE WHEN (code = 2 AND score > 50) or (code = 1 and s > 0) THEN 'Yes' ELSE 'No' end
  from my_table m, userscore;