postgresql 按多列分组,当连接条件失败时,填充组上的左连接数据

iqjalb3h  于 2023-08-04  发布在  PostgreSQL
关注(0)|答案(1)|浏览(131)

我有以下两个表:

test_data:

| 问题ID|应答ID|有效| valid |
| --|--|--| ------------ |
| q1| a1|真的| true |
| q1| A2|真的| true |
| q1| A3|假的| false |
| q1| A4|假的| false |
| q2| A5|真的| true |
| q2| A6|假的| false |
| q3| A7|真的| true |
| q3| A8|假的| false |
| q3| A9|假的| false |
| 四季度|A10|假的| false |
| 四季度|A11|假的| false |
| 四季度|a12|真的| true |

user_answers:

| 测试ID|问题ID|给定答案ID| given_answer_id |
| --|--|--| ------------ |
| t1| q1| a1| a1 |
| t1| q1| A3| a3 |
| t1| q2| A6| a6 |
| t2|四季度|A10| a10 |
| t2|四季度|a12| a12 |
我想得到以下结果:
| 测试ID|问题正确计数|问题错误计数| question_wrong_count |
| --|--|--| ------------ |
| t1|一个|二个| 2 |
| t2| 0个|一个| 1 |
| t1| 0个|三个| 3 |
| t2|一个|0个| 0 |
我的想法是test_data left join user_answers,然后继续group by user_id, test_id并执行所有的条件计数。
但是用户不需要回答所有问题,所以我在user_id列中有一些问题的NULL。缺失的测试或未回答的问题将被视为错误。举例来说:

  • u2没有完成t1,所以t1u2 hs 3个错误的问题。测试包含3个问题。
  • u1没有回答t1q3,因此q3计数为错误。
  • u1确实在q1中回答了a1a3,但即使a1是正确的,他也选择了a3而不是a2,所以这是错误的,所以q1也是错误的。
  • u1t2q4选择了错误的答案,因此他的t2有1个错误的问题(测试只有一个问题)

如何为user_answers表中的每个用户填充缺少的数据?

nlejzf6q

nlejzf6q1#

参见示例

with  res0 as ( -- test results
select a.user_id,a.test_id,a.question_id,a.given_answer_id,t.valid
from user_answers a
inner join test_data t on t.test_id=a.test_id and t.question_id=a.question_id
   and t.answer_id=given_answer_id 
)
,res as (-- one answer for one question
select a.user_id,a.test_id,a.question_id
  ,case when sum(case when valid='false' then -1 else 0 end)<0 then 'false' 
  else 'true' end valid
from res0 a
group by user_id,test_id,a.question_id
)
,resg as( -- result grouped
  select user_id,test_id
    ,sum(case when valid='true' then 1 else 0 end)valid_qty
    ,sum(case when valid='false' then 1 else 0 end)notvalid_qty
  from res
  group by user_id,test_id
)
,tests as( -- all tests and question count for every test
select test_id
  ,count(distinct question_id) test_question_qty
from test_data
group by test_id
)
select u.user_id,t.test_id
  ,coalesce(valid_qty,0) question_correct_count
  ,coalesce(test_question_qty,0)-coalesce(valid_qty,0) question_wrong_count
  ,test_question_qty,coalesce(valid_qty,0) valid_qty
  ,coalesce(notvalid_qty,0) notvalid_qty
  ,coalesce(test_question_qty,0)-coalesce(valid_qty,0)
       -coalesce(notvalid_qty,0) as notanswered_qty
from  (select distinct user_id from user_answers) u
left join tests t on 1=1 
left join resg g on g.user_id=u.user_id and t.test_id=g.test_id
;

字符串
| 测试ID|正确计数|错误计数|试题数量|有效|无效|未回答| notanswered |
| --|--|--|--|--|--|--| ------------ |
| t1|一个|二个|三个|一个|一个|一个| 1 |
| t2| 0个|一个|一个|0个|一个|0个| 0 |
| t1| 0个|三个|三个|0个|0个|三个| 3 |
| t2|一个|0个|一个|一个|0个|0个| 0 |

相关问题