[英]Excluding multiple results in specific column (SQL JOIN)
我正在實際生活中使用SQL方面邁出第一步。
我有一些包含合同和財務信息的表,並且查詢在某種程度上完全可以滿足我的需要。 看起來或多或少是這樣的:
SELECT /some columns/ from CONTRACTS
用INNER JOIN鏈接了3 extra tables
,以添加諸如部門名稱,產品信息等內容。這一切都可行,但是它們都具有簡單的一對一關系(在Department
表中有一個與單個部門相關的合同,在對應的表中有一個產品信息條目表等)。
現在這是我的挑戰:
我還需要添加合同發票信息,例如:
inner join INVOICES on CONTRACTS.contnoC = INVOICES.contnoI
(並選擇鏈接到Contract number
的Invoice number
Contract number
,盡管這是部分可選的)
我面臨的問題是,與其他表不同, INVOICES
表時總是存在一對一的關系, INVOICES
表可以有多個(或根本沒有)對應於單個合同編號的條目。 結果是,我將獲得單個合同編號(顯示不同發票編號)的多個查詢結果,從而不必要地擁擠了查詢結果。
本質上,我希望將INVOICES
表添加到查詢中,以僅識別INVOICES
表中是否存在合同編號(合同是否已開具發票)。 發票編號本身可以顯示(與INNER JOIN
),但是並不重要,只要它以某種方式被標記即可。 使用INNER JOIN
函數的結果中的Invoice number
字段保持空白,這也是必須的(即,即使在INVOICES
表中找不到匹配項,也要顯示行)。
SELECT DISTINCT
我的需要,但是我似乎面臨這樣一個問題,我只需要對代表合同編號的列而不是任何其他列征收DISTINCT
標准(可以提供相同的值,但是應該提供所有這些值) 。
不幸的是,我並不完全知道我使用的是哪個數據庫系統。
我會這樣:
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
這使您能夠將所有發票詳細信息都添加到查詢中,還可以完全控制要在主查詢中看到的發票。 請閱讀有關CTE的更多信息; 它們非常方便,比嵌套選擇更易於理解/閱讀。
我仍然不知道您正在使用哪個數據庫。 如果ROW_NUMBER
不可用,我會找出其他的方法:)
同樣,如果使用左聯接,則應使用COALESCE
函數,例如:
COALESCE(i.invoice_number,'0')
當然,這為您提供了更多可能性,例如,您可以在主選擇中執行以下操作:
CASE WHEN i.invoicenumber is null then 'NOT INVOICED'
else 'INVOICED'
END as isInvoiced
似乎這個問題仍在引起人們的注意,為了提供一些解釋,這里提供了一些技巧。
如果您只需要合同中包含從1到1表格中的詳細信息,則可以按照所描述的類似方式進行操作。 關鍵是不要在列列表中包含“發票”表中的任何列。
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
也許更干凈一點的是使用IN或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
不要使用IN!
如果您實際上想要所有合同,並且只知道合同是否已開票,則可以使用聚合和大小寫表達式:
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支持),或者可以根據系統使用帶TOP
或LIMIT
的計算列。
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
您可以使用SELECT ...,開票='是'...存在的地方...聯合SELECT ...,開票='否'...不存在的地方...
或者您可以將帶有“發票”的列與子查詢一起使用到發票中,以根據您是否點擊匹配項來設置其值
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.