SQL的新手,尽管很流行-卡在该查询上。 这可行,尽管不应显示Paddy O'Furniture,因为该作者没有写过任何书,并且au_id也没有出现在title_authors表中。请帮忙。
查找仅撰写历史书籍的作者
select a.au_id, a.au_lname, a.au_fname from authors a where not exists( select ta.au_id from title_authors ta join titles t on t.title_id = ta.title_id where t.type != 'history' and a.au_id = ta.au_id )
输出:
A01 Buchman Sarah
A07欧米茄稻草
答案 0 :(得分:1)
Paddy O'Furniture出现在您的结果中,因为在相关子查询中未找到匹配的行。即该作者没有exist
行,因此where not exists
为真。
select a.au_id, a.au_lname, a.au_fname
from authors a
inner join title_authors ta ON a.au_id = ta.au_id
inner join titles t on ta.title_id = t.title_id
group by a.au_id, a.au_lname, a.au_fname
having count(case when t.type <> 'history' then 1 end) = 0
以上方法在count()函数中使用了case表达式,因此,如果任何书籍具有非历史记录类型,则此计数将大于零。 having
子句允许使用聚合值来过滤最终结果(在group by
子句之后使用,不能代替where
子句)。
答案 1 :(得分:0)
您很近。在外部查询的JOIN
上添加title_authors
会过滤掉尚未写书的作者。
select a.au_id, a.au_lname, a.au_fname
from authors a
join title_authors ta1 on ta1.au_id = a.au_id
where not exists(
select 1
from title_authors ta
join titles t on t.title_id = ta.title_id
where t.type != 'history' and ta1.id = ta.id
)
内部查询中的title_authors
实际上可以删除。
select a.au_id, a.au_lname, a.au_fname
from authors a
join title_authors ta on ta.au_id = a.au_id
where not exists(
select 1
from titles
where t.type != 'history' and title_id = ta.title_id
)
答案 2 :(得分:0)
虽然如果您使用另一个exists
来确保作者至少写了一本历史书,那么您的方法也可以使用,但是这是使用conditional aggregation
的另一种方法:
select a.au_id, a.au_lname, a.au_fname
from authors a
join title_authors ta on a.au_id = ta.au_id
join titles t on ta.title_id = t.title_id
group by a.au_id, a.au_lname, a.au_fname
having sum(case when t.type != 'history' then 1 else 0 end) = 0