2012-09-27 74 views
0

我的表結構大致如下(有多個列,我離開了)檢查沒有主鍵的多個記錄中的不同

WEAPON MUNITION RANGE 

我正在寫一個查詢,以檢查一個表有許多WEAPON-MUNITION對具有不同的範圍。我需要找到每個實例的WEAPON-MUNITION有不同的範圍。允許複製,因爲此表中有多個數據集。是的,它違反規範化,但我沒有做到,我只需要查詢它。

所以說我有四個不同範圍的武器彈藥列隊,我需要能夠顯示他們,以便他們可以糾正。我已經嘗試了一些複雜的CTE,並且真正令人費解的自加入,但是當我認爲我有結果時,我無法將其與原始表綁定,因爲我認爲這是一個主鍵,在數據集之間存在重複!在找到上述記錄後,我需要顯示整個記錄。我最初幾乎是我開始的行的10倍,我無法弄清楚爲什麼。

缺少要求DBA允許我爲每條記錄生成唯一密鑰的問題我不知道我該如何實現這一點。

編輯 使用我想出了這個查詢gregmac的例子(一般,留下了一些列的任何專有信息)

WITH range_cte AS 
( 
    SELECT 
     d1.WEAPON 
     ,d1.MUNITION 
     ,d1.WEAPON 
     ,d1.RANGE 
     ,d1.ID --This is NOT a primary key! There are duplicates 
    FROM data1 d1 INNER JOIN data2 d2 
     ON d1.WEAPON = d2.WEAPON 
     AND d1.MUNITION = d2.MUNITION 
     AND d1.RANGE <> d2.RANGE 
    GROUP BY 
     d1.WEAPON 
     ,d1.MUNITION 
     ,d1.WEAPON 
     ,d1.RANGE 
     ,d1.ID 
    ORDER BY 
     d1.WEAPON 
     ,d1.MUNITION 
) 
--Self join the CTE on the original table using the ID (that's not a primary key) 
SELECT * FROM range_cte r INNER JOIN data d 
    ON r.ID = d.ID 

我的想法是插入一個自動生成的密鑰對整個或者是否應該在CTE中包含更多列(如數據集)以形成某種自然鍵?

+0

或許,如果你有一個查詢你已經嘗試過了,還有一個說明如果結果出了問題,我們可以更好地瞭解你想要做的事情。 – GilM

+0

我需要和我的主管覈對一下。我寫的所有代碼都是FOUO(僅供官方使用)。如果我犯了一個錯誤,併發布一些我不應該公開的東西,我可能會失去我的工作。 我會試着想出一個我已經寫過並由老闆運行它的通用示例。 – OpsResearch36

+0

我添加了一個例子。我希望這有助於澄清我爲什麼要嘗試去做。 – OpsResearch36

回答

1

除非我誤解,你需要簡單的自連接,並找到武器和彈藥是相同的其他行,但範圍是不同的。

我想出了這一點:

SELECT d1.* 
FROM data d1 
INNER JOIN data d2 
    ON d1.weapon = d2.weapon 
    AND d1.munition = d2.munition 
    AND d1.range <> d2.range 
GROUP BY d1.weapon, d1.munition, d1.range -- eliminate duplicates which are caused by joining both ways 
     ,d1.other1 ,d1.other2 
ORDER BY d1.weapon, d1.munition 

測試數據:

CREATE TABLE data 
(
    WEAPON varchar(20), 
    MUNITION varchar(20), 
    RANGE  varchar(20), 
    other1 varchar(20), 
    other2 varchar(20) 
); 

INSERT INTO data VALUES ('a', 'x', '1', 'aaa','aaa'); 
INSERT INTO data VALUES ('a', 'x', '2', 'aaa','bbb'); 
INSERT INTO data VALUES ('a', 'y', '3', 'aaa','bbb'); 
INSERT INTO data VALUES ('a', 'z', '4', 'ccc','ddd'); 
INSERT INTO data VALUES ('b', 'x', '5', 'def','ghh'); 
INSERT INTO data VALUES ('b', 'z', '6', 'ccc','ddd'); 
INSERT INTO data VALUES ('b', 'z', '7', 'aaa','aaa'); 
INSERT INTO data VALUES ('b', 'z', '8', 'aaa','bbb'); 
INSERT INTO data VALUES ('b', 'z', '9', 'aaa','ccc'); 

輸出:

WEAPON MUNITION RANGE other1 other2 
a  x   1  aaa  aaa 
a  x   2  aaa  bbb 
b  z   6  ccc  ddd 
b  z   7  aaa  aaa 
b  z   8  aaa  bbb 
b  z   9  aaa  ccc 

Sqlfiddle:http://sqlfiddle.com/#!6/65590/3/0

+0

謝謝!我有一個類似的查詢,但我錯過了Group By子句,消除了加入造成的重複!我會給這一槍! – OpsResearch36

+0

我編輯了我的原始問題以包含您的反饋。 – OpsResearch36

+0

@ OpsResearch36我想我不清楚..你還在問我的答案沒有回答? – gregmac

0

想法:創建一個包含所有武器彈藥配對和正確範圍的新表格。根據新表中的值更新原始表。

UPDATE o 
SET o.range = n.range 
FROM original AS o 
JOIN new AS n ON o.weapon = n.weapon 
    AND o.munition = n.munition 
0

我不能確定從描述,但也許你想是這樣的(以下簡稱「mytable的」 CTE只是我試圖生成測試數據的表,包括「othercolumn」,但有可能更多):

WITH mytable AS (
    SELECT * 
    FROM (
    VALUES('w1','m1',10, 'o1'), ('w1','m1',20, 'o2'), 
      ('w2','m2',10, 'o3'), 
      ('w3','m3',10, 'o4'), ('w3','m3',20,'o5'), ('w3','m3',30,'o6') 
    )x(weapon,munition,[range], othercolumn) 
), MultiRange AS (
SELECT weapon, munition FROM mytable 
GROUP BY weapon,munition 
HAVING COUNT(DISTINCT [range])>1 
) 
SELECT t.* 
FROM mytable t 
JOIN MultiRange m ON m.weapon = t.weapon AND m.munition = t.munition 
ORDER BY weapon, munition, [range] 
+0

我正在構建一個查詢來對數據庫中已有的表進行質量檢查。我們從外部來源獲取數據。它通過我們的VB.NET前端加載到各種數據庫中。這些數據輸入到模擬中,用戶不得不手動檢查範圍以確保匹配。一個乏味和耗時的任務。這個檢查應該在它被加載處理之前完成。 – OpsResearch36

相關問題