2016-12-29 69 views
0

我正在實際使用SQL中的第一步。排除特定列中的多個結果(SQL JOIN)

我有幾張合同和財務信息表,並且查詢的工作原理與我需要的完全一致 - 在某一點上。它看起來或多或少這樣的:

SELECT /some columns/ from CONTRACTS 

鏈接3 extra tables與INNER JOIN添加之類的東西的部門名稱,產品信息等,這一切工作,但他們都有一個simplish比一的關係(關係到一個合同單個部門Department表格,相應表格中的一個產品信息條目等)。

現在,這是我的挑戰:

我還需要補充合同發票信息做這樣的事情:

inner join INVOICES on CONTRACTS.contnoC = INVOICES.contnoI 

(和選擇也掛Contract number,雖然這部分是可選的Invoice number

我面臨的問題是,與其他表格不同的是,當連接表格時,總是存在一對一的關係,INVOICES表格可以有多個(或非電子郵件)與單個合同編號對應的條目。結果是,我將得到單個合同號的多個查詢結果(提供不同的發票號),不必要地擁擠查詢結果。

基本上我正在尋找將INVOICES表添加到查詢中,以確定INVOICES表(合同是否已開具發票)中是否存在合同號。發票號碼本身可以提供(它與INNER JOIN),但它不是關鍵,只要它以某種方式標記。 Invoice number字段在INNER JOIN函數的結果中保持空白,這也是必需的(即,即使未在INVOICES表中找到匹配,也要顯示該行)。

SELECT DISTINCT看起來做什麼,我需要,但我似乎要面對,我需要徵收僅列代表合同編號DISTINCT標準的問題,而不是任何其他列(可以有相同的價值觀呈現,但所有這些應被呈現)。

不幸的是我不完全知道我使用的是什麼數據庫系統。

+0

你好,告訴我們你嘗試過什麼,請 –

+0

如果你內加入像其他表的發票,但不把從發票表中的任何列到列的列表,並使用DISTINCT你還是應該讓你的1對1其他表格的結果。除此之外,您可以使用IN或EXISTS代替where子句並在那裏引用您的發票表。這個問題應該給你很多方法來解決這個問題。 http://stackoverflow.com/questions/173041/not-in-vs-not-exists – Matt

+0

它會更好,如果你顯示你的整個查詢和你的表結構... – barudo

回答

-1

您可以使用 SELECT ...,發票= 'YES' ...其中存在...... 工會 SELECT ...,發票= 'NO' ......哪裏都不存在...

,或者您可以使用列,如「發票」使用子查詢到發票來設置它取決於你是否得到一擊或沒有價值

1

我會做這種方式:

with mainquery as(
<<here goes you main query>> 
), 

invoices_rn as( 
select *, 
ROW_NUMBER() OVER (PARTITION BY contnoI order by 
<<some column to decide which invoice you want to take eg. date>>) as rn 
) 

invoices as (
select * from invoices_rn where rn = 1 
) 

select * from mainquery 
left join invoices i on contnoC = i.contnoI 

這使你有能力將所有的發票細節都提供給y我們的查詢,也讓您完全控制您想要在主要查詢中看到的發票。請閱讀有關CTE的更多信息;它們非常方便,比嵌套選擇更容易理解/讀取。

我仍然不知道你使用的是什麼數據庫。如果ROW_NUMBER不可用,我會找出別的東西:)

還與LEFT JOIN,你應該使用COALESCE功能,例如:

COALESCE(i.invoice_number,'0') 

當然,這給你一些更多的可能性,你可以爲例如,在你的主要選擇Do:

CASE WHEN i.invoicenumber is null then 'NOT INVOICED' 
else 'INVOICED' 
END as isInvoiced 
+1

如果OP想要除了其他信息之外還要返回特定的發票,這是一種很好的技術。支持公用表表達式和ROW_NUMBER()窗口函數的RDBM,實際上並不需要您的發票CTE,您可以直接連接到invoices_rn,然後在連接的ON子句中添加rn = 1。 – Matt

+0

你說得對。但我總是在2個CTE中做。只是我的習慣。 – cybernetic87

+0

我也認爲,對於一個begginer來說,它看起來更清楚,一步一步做。我是專業的數據倉庫程序員,我仍然用2個CTE來做,我發現它更容易閱讀和理解。我已經成爲CTE的怪胎。我的大多數vievs /程序都有很多CTE。 – cybernetic87

1

好像問題仍然得到一些關注,並努力在這裏提供一些解釋的一些技巧。

如果您只是想要從1到1表中的任何細節的合同,你可以做類似於你所描述的。關鍵是不在列列表中包含Invoices表中的任何列。

SELECT 
    DISTINCT Contract, Department, ProductId .....(nothing from Invoices Table!!!) 
FROM 
    Contracts c 
    INNER JOIN Departments D 
    ON c.departmentId = d.Department 
    INNER JOIN Product p 
    ON c.ProductId = p.ProductId 
    INNER JOIN Invoices i 
    ON c.contnoC = i.contnoI 

也許有點清潔劑將在使用或EXISTS像這樣:

SELECT 
    Contract, Department, ProductId .....(nothing from Invoices Table!!!) 
FROM 
    Contracts c 
    INNER JOIN Departments D 
    ON c.departmentId = d.Department 
    INNER JOIN Product p 
    ON c.ProductId = p.ProductId 
WHERE 
    EXISTS (SELECT 1 FROM Invoices i WHERE i.contnoI = c.contnoC) 

SELECT 
    Contract, Department, ProductId .....(nothing from Invoices Table!!!) 
FROM 
    Contracts c 
    INNER JOIN Departments D 
    ON c.departmentId = d.Department 
    INNER JOIN Product p 
    ON c.ProductId = p.ProductId 
WHERE 
    contnoC IN (SELECT contnoI FROM Invoices) 

不要在使用,如果SELECT ...列表可以返回NULL

如果你真的希望所有的合同,只是知道,如果合同已開發票,你可以用聚集和case表達式:

SELECT 
    Contract, Department, ProductId, CASE WHEN COUNT(i.contnoI) = 0 THEN 0 ELSE 1 END as Invoiced 
FROM 
    Contracts c 
    INNER JOIN Departments D 
    ON c.departmentId = d.Department 
    INNER JOIN Product p 
    ON c.ProductId = p.ProductId 
    LEFT JOIN Invoices i 
    ON c.contnoC = i.contnoI 
GROUP BY 
    Contract, Department, ProductId 

然後,如果你真的想返回有關特定發票的細節,你可以使用類似於cybercentic87的技術,如果您的RDBMS支持,或者您可以根據您的系統使用TOPLIMIT的計算列。

SELECT 
    Contract, Department, ProductId, (SELECT TOP 1 InvoiceNo FROM invoices i WHERE c.contnoC = i.contnoI ORDER BY CreateDate DESC) as LastestInvoiceNo 
FROM 
    Contracts c 
    INNER JOIN Departments D 
    ON c.departmentId = d.Department 
    INNER JOIN Product p 
    ON c.ProductId = p.ProductId 
GROUP BY 
    Contract, Department, ProductId