2017-12-27 128 views
0

我已經繼承了一個數據庫,並且在構建正在運行的SQL查詢時遇到了問題。獲取帶有附加信息的重複項

假設這是數據:

[Products] 

| Id | DisplayId  | Version | Company | Description | 
|---- |----------- |---------- |-----------| ----------- | 
| 1  | 12345   | 0   | 16  | Random  | 
| 2  | 12345   | 0   | 2   | Random 2  | 
| 3  | AB123   | 0   | 1   | Random 3  | 
| 4  | 12345   | 1   | 16  | Random 4  | 
| 5  | 12345   | 1   | 2   | Random 5  | 
| 6  | AB123   | 0   | 5   | Random 6  | 
| 7  | 12345   | 2   | 16  | Random 7  | 
| 8  | XX45   | 0   | 5   | Random 8  | 
| 9  | XX45   | 0   | 7   | Random 9  | 
| 10 | XX45   | 1   | 5   | Random 10  | 
| 11 | XX45   | 1   | 7   | Random 11  | 


[Companies] 

| Id | Code  | 
|---- |-----------| 
| 1  | 'ABC'  | 
| 2  | '456'  | 
| 5  | 'XYZ'  | 
| 7  | 'XYZ'  | 
| 16 | '456'  | 

Version列是一個版本號。數字越大表示更新的版本。 Company列是Id列中引用Companies表的外鍵。 還有另一個表ProductDataProductId列參考Products.Id

現在我需要根據DisplayId和相應的Companies.Code找到重複項。應加入ProductData表以顯示標題(ProductData.Title),並且只有最近的應該包含在結果中。因此,預期的結果是:

| Id | DisplayId  | Version | Company | Description | ProductData.Title | 
|---- |----------- |---------- |-----------|------------- |------------------ | 
| 5  | 12345   | 1   | 2   | Random 2  | Title 2   | 
| 7  | 12345   | 2   | 16  | Random 7  | Title 7   | 
| 10 | XX45   | 1   | 5   | Random 10  | Title 10   | 
| 11 | XX45   | 1   | 7   | Random 11  | Title 11   | 
  • 因爲XX45有2個「項」:一個公司5和一個與公司7,但兩家公司共享相同的代碼。
  • 因爲12345有2個「條目」:一個與公司2和一個與公司16,但兩家公司共享相同的代碼。請注意,兩者的最新版本不同(公司16的條目的版本2和公司2的條目的版本1)
  • 不應包含ABC123,因爲它的2個條目具有不同的公司代碼。

我很想知道您的見解...

回答

0

試試這個:

SELECT b.ID,displayid,version,company,productdata.title 
FROM 
(select A.ID,a.displayid,version,a.company,rn,a.code, COUNT(displayid) over (partition by displayid,code) cnt from 
(select Prod.ID,displayid,version,company,Companies.code, Row_number() over (partition by displayid,company order by version desc) rn 
from Prod inner join Companies on Prod.Company = Companies.id) a 
where a.rn=1) b inner join productdata on b.id = productdata.id where cnt =2 
+0

乍看起來,這似乎是工作!讓我測試一些,並接受你的答案,如果一切似乎罰款。 – Propaganistas

+0

檢查,如果它工作與否。 – Anagha

1

如果我理解正確的話,你可以使用CTE從您的表發現所有的重複的行,那麼你可以只使用來自SELECT CTE甚至添加更多操作。

WITH CTE AS(
    SELECT Id,DisplayId,Version,Company,Description,ProductData.Title 
     RN = ROW_NUMBER()OVER(PARTITION BY DisplayId, Company ORDER BY p.Id DESC) 
    FROM dbo.YourTable1 
) 

SELECT * 
FROM CTE 
+0

需要通過公司還 –

+0

@DmitrijKultasev你的權利,我編輯我的回答分區。謝謝。 – ShaiEitan

+0

您沒有執行Company.Code重複標準?只應包含具有重複的Company.Code + DisplayId的行。公司ID可以不同;該檢查應在公司進行。代碼 – Propaganistas

1

根據您的樣本數據,你只需要JOIN表:

SELECT 
    p.Id, p.DisplayId, p.Version, p.Company, d.Title 
    FROM Products AS p 
    INNER JOIN Companies AS c ON p.Company = c.Id 
    INNER JOIN ProductData AS d ON d.ProductId = p.Id; 

但是如果你想要最新的一個,你可以使用ROW_NUMBER()

WITH CTE 
AS 
(
    SELECT 
    p.Id, p.DisplayId, p.Version, p.Company, d.Title, 
    ROW_NUMBER() OVER(PARTITION BY p.DisplayId,p.Company ORDER BY p.Id DESC) AS RN 
    FROM Products AS p 
    INNER JOIN Companies AS c ON p.Company = c.Id 
    INNER JOIN ProductData AS d ON d.ProductId = p.Id 
) 
SELECT * 
FROM CTE 
WHERE RN = 1; 

sample fiddle

| Id | DisplayId | Version | Company | Title | 
|----|-----------|---------|---------|----------| 
| 5 |  12345 |  1 |  2 | Title 5 | 
| 7 |  12345 |  2 |  16 | Title 7 | 
| 10 |  XX45 |  1 |  5 | Title 10 | 
| 11 |  XX45 |  1 |  7 | Title 11 | 
+0

你沒有實現'Company.Code'重複標準?只有包含重複的Company.Code + DisplayId的行應該包含在內 – Propaganistas

0

您必須先獲取當前版本,然後才能看到DisplayID +代碼顯示的次數。然後基於此,您只能選擇計數大於1的計數。然後,您可以在最終查詢上INNER JOIN ProductData以獲取標題。

WITH 
MaxVersion AS --Get the current versions 
(
    SELECT 
     MAX(Version) AS Version, 
     DisplayID, 
     Company 
    FROM 
     #TmpProducts 
    GROUP BY 
     DisplayID, 
     Company 
) 
,CTE AS 
(
    SELECT 
     p.DisplayID, 
     c.Code, 
     COUNT(*) AS RowCounter 
    FROM 
     #TmpProducts p 
    INNER JOIN 
     #TmpCompanies c 
     ON 
      c.ID = p.Company 
    INNER JOIN 
     MaxVersion mv 
     ON 
      mv.DisplayID = p.DisplayID 
     AND mv.Version = p.Version 
     AND mv.Company = p.Company 
    GROUP BY 
     p.DisplayID, 
     c.Code 
) 

SELECT 
    p.* 
FROM 
    #TmpProducts p 
INNER JOIN 
    CTE c 
    ON 
     c.DisplayID = p.DisplayID 
INNER JOIN 
    MaxVersion mv 
    ON 
     mv.DisplayID = p.DisplayID 
    AND mv.Company = p.Company 
    AND mv.Version = p.Version 
WHERE 
    c.RowCounter > 1