外部连接到计数表时完成缺少的行

时间:2017-03-16 08:55:04

标签: sql oracle

我有一个OUTER JOIN没有提供足够空行的问题。

业务环境是用户开始(并希望完成)在线测试。每个用户可以多次尝试每个测试。

我正在尝试报告每个用户启动/完成每项测试的次数。特别是,对于每个尝试过至少一次测试的用户,我想为每个测试显示一行计数(甚至是他们根本没有尝试过的计数)。

TEST表非常简单。

    ID  NAME
    --  ----
    1   Test 1
    2   Test 2

PROGRESS表提供测试和用户组合的计数。

    TEST_ID  USER_ID  NUM_TIMES_STARTED  NUM_TIMES_FINISHED
    -------  -------- -----------------  ------------------
    1        Alice    2                  1
    1        Bob      1                  0    

我想看到的是以下内容(第2行和第4行是关键行):

    USER_ID  TEST_NAME  TIMES_STARTED  TIMES_FINISHED
    -------  ---------  -------------  --------------
    Alice    Test 1     2              1
    Alice    Test 2     0              0
    Bob      Test 1     1              0
    Bob      Test 2     0              0

我试图产生这个:

    SELECT p.user_id, t.name, COALESCE(p.num_times_started, 0), 
        COALESCE(p.num_times_finished, 0)
    FROM test t
    LEFT OUTER JOIN progress p
    ON t.id = p.test_id
    ORDER BY p.user_id, t.id

但是这不会重复测试2的缺失行,每个用户一次 - 我只需再追加一行。

    USER_ID  TEST_NAME  TIMES_STARTED  TIMES_FINISHED
    -------  ---------  -------------  --------------
    Alice    Test 1     2              1
    Bob      Test 1     1              0
    (null)   Test 2     0              0

我缺少的是如何在代理级别应用外部联接生成的额外行,而不是整个数据集......

(数据库服务器是Oracle 9i。我无法对表结构进行任何更改。)

非常感谢你的想法。

2 个答案:

答案 0 :(得分:3)

在CTE中交叉连接,左连接数据

with CTE as
(
select distinct user_id, test_name
from Progress
cross join test
)
select CTE.*, 
       COALESCE(p.num_times_started, 0), 
       COALESCE(p.num_times_finished, 0)
from CTE
left join progress p
  on p.user_id = CTE.user_ID
  and p.test_id = CTE.test_id

答案 1 :(得分:2)

<PropertyGroup Condition="'$(ConfigurationType)' == 'Executable'"> <LinkCompiled>true</LinkCompiled> <TargetExt></TargetExt> <OutputType>exe</OutputType> <TargetName Condition="'$(TargetName)' == ''">$(RootNamespace)</TargetName> </PropertyGroup> 参加考试的不同用户:

CROSS JOIN