2017-06-18 125 views
1

我有3個表格:Book,Invoice,Download最後兩個有外鍵的Book。我需要知道每本書的成功發票和下載數量。爲了得到結果,我有2個查詢。第一個顯示號碼的發票爲每本書:兩個連接的合併結果

select b.Title, sum(i.price) 
from Book b, Invoice i 
where i.BookId = b.Id and i.State = 'successful' 
group by b.Title 

,最後一個顯示下載數量爲每本書:

select b.Title, count(1) 
from Book b, Download d 
where d.BookId = b.Id and d.State = 'successful' 
group by b.FarsiTitle 

我想看到的結果作爲一個單一的表,所以我有3列:

BOOK_TITLE,invoice_count,DOWNLOAD_COUNT

這怎麼可能?

+0

*不要*使用逗號'FROM'子句。 *總是*使用正確的,明確的'JOIN'語法。 –

+0

謝謝戈登。但爲什麼我應該使用'JOIN'而不是從'from'擴展? –

+0

FROM子句中的逗號是古老的語法,不如'JOIN'強大。我們在21世紀,所以我們應該使用現代的,標準的SQL語言。 –

回答

3

我認爲最簡單的方法是相關子查詢:

select b.*, 
     (select count(*) 
     from invoice i 
     where i.BookId = b.Id and i.State = 'successful' 
     ) as num_invoices, 
     (select count(*) 
     from download d 
     where d.BookId = b.Id and d.State = 'successful' 
     ) as numdownloads 
from book b; 

如果你想使用JOIN,那麼你就需要聚集JOIN之前得到正確的計數。

編輯:

在SQL Server中,你可以使用outer apply

select b.*, i.num_invoices, i.price, d.numdownloads 
from book b outer apply 
    (select count(*) as num_invoices, sum(i.price) as price 
     from invoice i 
     where i.BookId = b.Id and i.State = 'successful' 
    ) i outer apply 
    (select count(*) as numdownloads 
     from download d 
     where d.BookId = b.Id and d.State = 'successful' 
    ) d; 

這是非常相似的相關子查詢,但可以讓你做多個計算。

+0

謝謝。似乎是正確的。因此,我可以在'從書b'中放入'group by'子句,並將where子句中的其他條件放在Book上。但是這不會造成任何性能問題? –

+0

@AbouzarNouri。 。 。沒有'group by'是必要的。您可以在'from'子句之後的'book'上添加'where'條件。 –

+0

啊!你是對的:) –

0

一個簡單的工會所有的罰款如下:

select b.Title, sum(i.price) 
from Book b join Invoice i 
on i.BookId = b.Id and i.State = 'successful' 
group by b.Title 

UNION ALL 

select b.Title, count(1) 
from Book b join Download d 
on d.BookId = b.Id and d.State = 'successful' 
group by b.FarsiTitle 
+0

我認爲這是錯誤的。因爲我需要合併基於書名的結果,所以有三列。 –