我有两张桌子:
东西:
#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.
答案 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)
从Things
(type = '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 - 因为您选择了一个非常通用的设计,原因有这个缺点。)