如何连接表以获得正确的结果?

时间:2017-02-27 19:28:30

标签: sql oracle join

我有两张桌子:

东西:

#include <ctype.h>

int strisalpha(const char *str) {
    while (*str) {
        if (!isalpha((unsigned char)*str++)
            return 0;
    }
    return 1;
}

链接:

+----+---------+--+
| id |  type   |  |
+----+---------+--+
|  1 | issue   |  |
|  2 | issue   |  |
|  3 | issue   |  |
|  4 | issue   |  |
|  5 | issue   |  |
|  6 | bug     |  |
|  7 | bug     |  |
|  8 | bug     |  |
|  9 | bug     |  |
| 10 | bug     |  |
| 11 | project |  |
| 12 | project |  |
+----+---------+--+

我想列出第一列中所有类型问题以及第二列中所有连接的错误(link_type = i_b)。如果没有连接错误,则应该+----+--------+-------------+-----------+ | id | source | destination | link_type | +----+--------+-------------+-----------+ | 1 | 1 | 6 | i_b | | 2 | 2 | 7 | i_b | | 3 | 3 | 8 | i_b | | 4 | 1 | 10 | i_p | | 5 | 2 | 11 | i_p | | 6 | 3 | 10 | i_p | | 7 | 4 | 11 | i_p | | 8 | 5 | 10 | i_p | +----+--------+-------------+-----------+

NULL

我尝试使用连接进行此操作,但无法获取没有连接错误的问题的行:

+----------+--------+
| issue_id | bug_id |
+----------+--------+
|        1 | 6      |
|        2 | 7      |
|        3 | 8      |
|        4 | NULL   |
|        5 | NULL   |
+----------+--------+

结果:

select issue.id as issue, bug.id
from things issue
    left join links
        on issue.id = links.source
    join things bug
        on links.destination = bug.id

缺少问题4和5.

5 个答案:

答案 0 :(得分:1)

我认为您需要第二次加入才能成为左连接:

select issue.id as issue, bug.id
from things issue
    left join links
        on issue.id = links.source
    left join things bug
        on links.destination = bug.id

答案 1 :(得分:1)

检查源是否是“问题”只需要半连接(IN条件,比完整连接便宜)。您还需要区分具有问题ID和非错误目标的行,具体取决于目标 错误的其他行可能存在。这需要的不仅仅是连接。我通过调用子查询中的分析函数count()来解决这个问题。

with things ( id, type ) as (
       select  1, 'issue'   from dual union all
       select  2, 'issue'   from dual union all     
       select  3, 'issue'   from dual union all
       select  4, 'issue'   from dual union all
       select  5, 'issue'   from dual union all
       select  6, 'bug'     from dual union all
       select  7, 'bug'     from dual union all
       select  8, 'bug'     from dual union all
       select  9, 'bug'     from dual union all
       select 10, 'bug'     from dual union all
       select 11, 'project' from dual union all
       select 12, 'project' from dual
     ),
     links(  id, source, destination, link_type ) as (
       select 1, 1,  6, 'i_b' from dual union all
       select 2, 2,  7, 'i_b' from dual union all
       select 3, 3,  8, 'i_b' from dual union all
       select 4, 1, 10, 'i_p' from dual union all
       select 5, 2, 11, 'i_p' from dual union all
       select 6, 3, 10, 'i_p' from dual union all
       select 7, 4, 11, 'i_p' from dual union all
       select 8, 5, 10, 'i_p' from dual
     )
-- end of test data (NOT part of the solution); query begins BELOW THIS LINE
select issue, bug
from ( select l.source as issue,
              case when t.type = 'bug' then l.destination end as bug, 
              count(case when t.type = 'bug' then 1 end) 
                                 over (partition by l.source) as ct
       from   links l inner join things t on l.destination = t.id
       where  l.source in (select id from things where type = 'issue')
     )
where bug is not null or ct = 0
;

<强>输出

ISSUE BUG
----- ---
    1   6
    1  10
    2   7
    3   8
    3  10
    4
    5  10

7 rows selected.

答案 2 :(得分:0)

希望,我理解正确。 请查看以下查询。

select issue.id as issue, bug.id from things  
left outer join links
on issue.id = links.destination 
where a.type = 'issue';

答案 3 :(得分:0)

如果我们假设(如您的示例数据中)所有问题都在links中,那么您只需要一次加入。另外,我想你想检查一下&#34; bug&#34;在类型列中:

select l.source as issue, bug.id
from links l left join
     things bug
     on bug.id = l.destination and bug.type = 'bug';

如果这是假设不正确,您可以issues使用两个left join s:

select l.source as issue, bug.id
from issues i left join
     links l
     on i.id = l.source left join
     things bug
     on bug.id = l.destination and bug.type = 'bug';

答案 4 :(得分:0)

Thingstype = 'issue')中选择问题。将错误链接到问题的外部联接Links(即link_type = 'i_b')。

select
  t.id as issue_id,
  l.destination as bug_id
from things t
left join links l on l.source = t.id and l.link_type = 'i_b'
where t.type = 'issue';

(您可以向'bug' Things条记录添加外部联接,但是您什么也得不到。除了可能针对无效Links条目的保险外。数据库无法真正保证数据的完整性 - 例如'i_b'记录确实包含问题ID和错误ID - 因为您选择了一个非常通用的设计,原因有这个缺点。)