BookID Title ReleaseYear
1 The Hobbit 1937
2 Atlas Shrugged 1957
BookID Cost BookPrinterID
1 12 38
BookID Charge BookPublisherID
1 39 148
2 45 151
这是我出版的表格数据 书籍表,成本表和收费表 我希望看到成本信息,如果存在其他收费来自单个查询。即。
BookID Cost
1 12
2 45
这是我的查询
select Books.BookID, ISNULL(Cost.Cost, Charge.Charge) AS Cost
from Books
left join Cost on Books.BookID = Cost.BookID
left join Charge on Book.BookID = Charge.BookID
这样可行,但问题是如果有更多的表要连接或要检索更多的列,每个列的ISNULL条件将成为一大块文本,特别是如果你必须解析xml。
ISNULL(Cost.Xchange.value('/Partner[1]/@Sales[1]', 'nvarchar(500)'), Charge.Xchange.value('/Partner[1]/@Sales[1]', 'nvarchar(500)')) AS Xchange
我的问题是,是否有更简洁的方式来编写此查询?
答案 0 :(得分:0)
在两个表上使用INNER join
将省略bookid=2
的行,因为cost
表中没有记录。对于两个表,您可能希望使用LEFT OUTER JOIN
而不是INNER JOIN
来显示所有行。
那就是说,你想要的是某种中间表,它是cost
/ charge
的组合,但只有当cost
中没有记录时才会这样。
您可以执行以下操作:在其中填充包含所有cost
条记录的新表格,然后填写所有charge
条记录(在新表格中找不到cost
)......虽然,动态创建/写入新表无疑会对性能造成影响。我不想在一个大型图书馆里这样做。
这里也是sql fiddle。
create table #books (bookid int, title varchar(50), releaseyear int)
create table #charge (bookid int, charge money, publisherid int)
create table #cost (bookid int, cost money, bookprinterid int)
insert into #books
select 1, 'The Hobbit', 1937 union
select 2, 'Atlas Shrugged', 1957
insert into #cost
select 1, 12, 38
insert into #charge
select 1, 39, 148 union
select 2, 45, 151
create table #allcosts (bookid int, cost money)
insert into #allcosts
select c1.bookid, c1.cost from #cost c1
insert into #allcosts
select c2.bookid, c2.charge
from #charge c2
left outer join #allcosts c3 on c2.bookid=c3.bookid
where c3.bookid is null
select b.BookID, c.cost AS Cost
from #Books b
inner join #allcosts c on b.bookid = c.bookid
答案 1 :(得分:0)
如果Books中的所有行都不在Cost中,则无法在3个表上使用内部联接。否则,在您的示例中,将永远不会返回BookID = 2。如果要连接更多表并检索更多列,则无法使用isNull。
select bookid, isNull(cost, charge)
from Books b
inner join Charge c
on bt.bookid = c.bookid
left join Cost co
on co.bookid = bt.bookid