简体   繁体   English

联接表以从一个或另一个表中选择数据的更好方法

[英]Better way to joining tables to pick data from one or other table

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

That's the book publishing tables data I have. 那就是我拥有的图书出版表格数据。
Books table, Cost table and Charge table. 帐簿表,成本表和费用表。
I would like to see cost information if present else charge data from single query. 我想查看成本信息(如果存在),否则会从单个查询中收取费用数据。 ie

BookID  Cost
1       12
2       45

This is my query 这是我的查询

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

That works, but problem is if there are more tables to join or more columns to retrieve, having ISNULL condition for every column will become a big blob of text, especially if you have to parse xml. 那行得通,但是问题是,如果要连接更多表或要检索更多列,则每列具有ISNULL条件将成为一大堆文本,尤其是在必须解析xml时。

ISNULL(Cost.Xchange.value('/Partner[1]/@Sales[1]', 'nvarchar(500)'), Charge.Xchange.value('/Partner[1]/@Sales[1]', 'nvarchar(500)')) AS Xchange

My question is, is there a neater way to write this query? 我的问题是,有没有更整洁的方式编写此查询?

Using an INNER join on both tables, will omit the row for bookid=2 as there is no record in the cost table for it. 在两个表上都使用INNER join bookid=2 ,将省略bookid=2的行,因为它在cost表中没有记录。 You likely want to use LEFT OUTER JOIN instead of INNER JOIN for both tables to show all rows. 您可能想对两个表使用LEFT OUTER JOIN而不是INNER JOIN来显示所有行。

That said, what you want is some sort of intermediate table that is a combination of cost / charge but only when there is no record in cost . 就是说,您想要的是某种中间表,该中间表是cost / charge的组合,但仅当没有cost记录时cost

You could do something like this, where you populate a new table with all the cost records, and then all the charge records (where no cost is found in the new table)... Although, there would undoubtedly be a performance hit by creating/writing to a new table on the fly. 您可以执行类似的操作,在该表中先填充所有cost记录,然后填充所有charge记录(在新表中未找到cost )...虽然,无疑会因创建/动态地写入新表。 I wouldn't want to do this in a large library. 我不想在大型图书馆中这样做。

Here's a sql fiddle too. 这也是一个SQL提琴

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

If all rows in Books are not in Cost you can't use inner joins on the 3 tables. 如果“书籍”中的所有行均不在“成本”中,则不能在这3个表上使用内部联接。 Otherwise in your example BookID=2 will never be returned. 否则,在您的示例BookID = 2中将永远不会返回。 There is no way around using isNull if you are going to join more tables and retrieve more columns. 如果要联接更多表并检索更多列,则无法使用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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 mysql 每行将一个表的数据与其他表连接起来 - mysql joining one table's data with other tables each row 将一个表多次连接到其他表 - joining one table multiple times to other tables 通过一个其他表将一个表连接到另一个表 - Joining one table through other tables to another 连接表是否比直接放入另一个表的字符串更好? - Is joining tables is better than putting the string of the other table directly? 当一个表具有大量数据而另一个表具有少量数据时,在SQL Server中联接两个表 - Joining two tables in SQL Server when one table has huge data and other has few data SQL连接其他表中的数据 - SQL joining data from other tables 通过ID连接两个数据表,但一个表的ID比另一个多5 - Joining two tables of data via ID but the ID for one table is 5 more that the other 根据一张表中的纬度和经度是否存在于另一张表的多边形中来连接两张表(来自不同的数据库) - Joining two tables (from different databases) based on whether lat and long from one table are present in the polygon of the other 连接两个表,其中一个表中有多个与另一个表中的一行相关的行 - Joining two tables, which in one there are multiple Lines related to a single line from the other table 需要更好的方法来从原始数据对现有表进行质量检查。 子数据原始数据设置和联接到现有表不是最佳方法 - Need better way to QA existing table from raw data. Subsetting raw data and joining to existing table isn't the best method
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM