我有两张桌子,一张是书,另一张是版本。每个版本在“edtype”列中都有“精装”或“平装”等属性。每个图书行可以有多个版本行。
select books.id, books.name, editions.id, editions.edtype from books
join editions on books.id=editions.bookid;
会返回类似的内容:
1 name1 1 hardback
1 name1 2 paperback
2 name2 3 paperback
3 name3 4 hardback
我想要做的是找到有(1)精装版和平装版的书籍:
1 name1
(2)平装书但不是精装版
2 name2
(3)精装本但不是平装版
3 name3
我有以下查询,我认为(1),但我不太相信(因为它返回的行数显得太低):
select id, name
from books
left join editions e1 on ( books.id = e1.bookid and e1.edtype = 'paperback')
left join editions e2 on ( books.id = e2.bookid and e2.edtype = 'hardback')
where e1.edtype is not null
and e2.edtype is not null
group by b_id
;
虽然我现在只关注两个属性,但能够将其扩展到版本表中的多个匹配属性会很棒。
感激不尽的任何帮助。
答案 0 :(得分:0)
让我们从您的查询开始,改进一下以使用表别名并具有不同的列名:
select b.id as book_id, b.name, e.id as edition_id, e.edtype
from books b join
editions e
on b.id = e.bookid;
您想要查找图书,以便建议通过图书进行汇总。然后我们需要做一些事情来理解edtype
。试试这个:
select b.id as book_id, b.name,
(case when min(edtype) = max(edtype)
then min(edtype)
else 'Both'
end) as EdTypes
from books b join
editions e
on b.id = e.bookid;
group by b.id, b.name;
答案 1 :(得分:0)
按照上面的Gordon代码,我提出了几个子查询,我认为这就是我需要的(至少如果我只比较两个属性):
select * from (
select books.name, bookid, (case when min(edtype) = max(edtype)
then min(edtype)
else 'Both'
end) as EdTypes
from
(select * from editions where (edtype = 'paperback' or edtype = 'hardback'))
as e2
join books on e2.bookid = books.id
group by bookid
) as titlelist
where edtypes = 'Both';
所以,首先选择你感兴趣的行 - 所以你有一个有意义的最小值和最大值。然后处理case语句,加入书籍并消除重复。然后依次选择每种类型以获得计数。