Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 连接表以从一个或另一个表中拾取数据的更好方法_Sql_Sql Server_Join - Fatal编程技术网

Sql 连接表以从一个或另一个表中拾取数据的更好方法

Sql 连接表以从一个或另一个表中拾取数据的更好方法,sql,sql-server,join,Sql,Sql Server,Join,这是我拥有的图书出版表数据。 图书表、成本表和收费表。 我想查看成本信息,如果存在其他来自单个查询的费用数据。i、 e BookID Title ReleaseYear 1 The Hobbit 1937 2 Atlas Shrugged 1957 BookID Cost BookPrinterID 1 12 38 BookID Charge BookPublisherID 1 39

这是我拥有的图书出版表数据。
图书表、成本表和收费表。
我想查看成本信息,如果存在其他来自单个查询的费用数据。i、 e

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
这是可行的,但问题是,如果有更多的表要连接,或者有更多的列要检索,那么为每个列设置ISNULL条件将成为一个大的文本块,特别是当您必须解析xml时

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

我的问题是,有没有更简洁的方法来编写此查询?

在两个表上使用
内部联接将省略
bookid=2
的行,因为
成本
表中没有该行的记录。您可能希望对两个表使用
左外部联接
而不是
内部联接
,以显示所有行

也就是说,您需要的是某种中间表,它是
成本
/
费用
的组合,但只有在
成本
中没有记录时才需要

您可以这样做,在新表中填充所有
成本
记录,然后填充所有
费用
记录(在新表中找不到
成本
)。。。尽管如此,动态创建/写入新表无疑会影响性能。我不想在大图书馆里这样做

这也是一个例子


如果帐簿中的所有行都没有成本,则不能在3个表上使用内部联接。否则,在您的示例中,BookID=2将永远不会返回。如果您要连接更多的表并检索更多的列,那么就没有办法使用isNull

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

我会尽可能给出最短的答案——不!你如何期望在没有实际操作的情况下查询某个内容?您仅在必要时使用函数。某些列永远不会为空。您可以使用
限制数据输出,其中Cost.Cost不为null
,您的数据将永远不会为null。但是,是的,你必须写东西我应该用临时表吗?这比我的还要糟糕。不,你不必使用临时表,那只是为了演示。但是,如果您选择的是临时表,那么它可以很容易地动态索引。我完全同意,此解决方案的性能可能比您当前的解决方案更差。对不起,我的不好。我离开了那里。我的问题是,有没有更好的方法来编写上述查询,而不是对这么多列执行isnull。基本上是寻找一个较短的版本,希望它会更整洁。
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
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