2014-11-04 55 views
0

我有這個表:SQL查詢同一個表內連接消除重複

CREATE TABLE [BGIA].[INTCOL004VA](
[ID] [int] NOT NULL, 
[DATYEN] [varchar](18) NULL, 
[ZZRIDN] [varchar](8) NULL, 
[OQTIEF] [varchar](1) NULL, 
[OQMONE] [varchar](3) NULL, 
[ZZPONR] [varchar](3) NULL, 
[ZZNBRE] [varchar](15) NULL, 
[ZZPDSE] [varchar](22) NULL 
); 

    INSERT INTO INTCOL004VA VALUES 
('53671955', 'MC1141103006', '38565363', '1', '007', '010', '0', '0'), 
('53671956', 'MC1141103006', '38565363', '0', NULL, '020', '0', '0'), 
('53671957', 'MC1141103006', '38565363', '0', '007', '030', '1', '500'), 
('53671958', 'VT1141103010', '38565421', '1', '007', '050', '0', '0'), 
('53671959', 'VT1141103010', '38565421', '0', NULL, '100', '0', '0'), 
('53671960', 'ST1141103006', '38587542', '0', NULL, '010', '1', '500'), 
('53671961', 'ST1141103006', '38587542', '1', 'B01', '020', '5', '0'); 

記錄由DATYEN,ZZRIDN和ZZPONR

我想這個規則更新錶鏈接:

  • 對於一個鏈接DATYEN,ZZRIDN如果ZZNBRE上的一行不是0並且ZZPDSE => OQTIEF = 0並且OQMONE = NULL
  • 但是對於一個鏈接DATYNE,ZZRIDN如果所有行都是a在ZZNBRE和ZZPDSE和一個行r 0有OQTIEF = 1和OQMONE不是null =>適用於所有的行AF鏈接OQTIEF = 1和OQMONE =不空行

我不能做的OQMONE與INNER JOIN突然,我不知道如何成功

謝謝:)

編輯:對於爲例,這樣的:

('53671955', 'MC1141103006', '38565363', '1', '007', '010', '0', '0'), 
('53671956', 'MC1141103006', '38565363', '0', NULL, '020', '0', '0'), 
('53671957', 'MC1141103006', '38565363', '0', '007', '030', '1', '500') 

必須是:

('53671955', 'MC1141103006', '38565363', '0', NULL, '010', '0', '0'), 
('53671956', 'MC1141103006', '38565363', '0', NULL, '020', '0', '0'), 
('53671957', 'MC1141103006', '38565363', '0', NULL, '030', '1', '500') 

因爲組MC1141103006和38565363有一行與ZZNBRE和ZZPDSE不爲0

此:

('53671960', 'ST1141103006', '38587542', '0', NULL, '010', '1', '500'), 
('53671961', 'ST1141103006', '38587542', '1', 'B01', '020', '5', '0') 

必須是:

('53671960', 'ST1141103006', '38587542', '0', NULL, '010', '1', '500'), 
('53671961', 'ST1141103006', '38587542', '0', NULL, '020', '0', '0') 

因爲組ST1141103006和38587542有一排用ZZNBRE和ZZPDSE不是0,而是將ZZNBRE設置爲0,因爲ZZPDSE爲0

這:

('53671958', 'VT1141103010', '38565421', '1', '007', '050', '0', '0'), 
('53671959', 'VT1141103010', '38565421', '0', NULL, '100', '0', '0') 

必須是:

('53671958', 'VT1141103010', '38565421', '1', '007', '050', '0', '0'), 
('53671959', 'VT1141103010', '38565421', '1', '007', '100', '0', '0') 

因爲所有的行具有ZZNBRE和ZZNBRE 0

我希望能準確地說,是不容易理解我猜:(

編輯2:其實我的查詢是:

update v1 
set v1.zznbre = (case when v1.zzpdse = 0 then 0 else v1.zznbre end), 
v1.oqtief = (case when v1.zznbre = 0 and v2.zznbre = 0 and v1.zzpdse = 0 and v2.zzpdse = 0 then 1 else 0 end), 
v1.oqmone = (case when v1.zznbre = 0 and v2.zznbre = 0 and v1.zzpdse = 0 and v2.zzpdse = 0 then v2.oqmone else null end) 
from intcol004va v1 
inner join intcol004va v2 on v2.datyen = v1.datyen and v2.zzridn = v1.zzridn and v2.id <> v1.id 
where v2.oqtief = 1 and v2.oqmone is not null and v1.oqtief <> v2.oqtief 

但在所有情況下無法正常工作:(

+2

你能解釋一下更新規則嗎?目前還不清楚 – 2014-11-04 13:34:30

+1

您可以請用正常名字嗎? – SubqueryCrunch 2014-11-04 13:39:57

+2

歡迎來到Stack Overflow!我們很高興見到你:)這樣發佈你的全表結構非常有幫助,我們非常感謝。正如其他人指出的,但是,你的問題有點難以理解。你能告訴我們任何SQL或樣本數據,這將使你的規則更清晰一些嗎?也許建立一個SQL Fiddle示例,以便我們可以看到你在說什麼? – AHiggins 2014-11-04 13:48:01

回答

0

如果將更新作爲兩個獨立更新進行處理,它似乎會生成正確的答案集。 我包含一個結果表和代碼,它將顯示原始數據與您的描述中定義的所需結果表之間的比較。

接下來,它將執行兩次更新,然後顯示已加入的原始表和目標表,以證明它們已正確對齊。

CREATE TABLE [INTCOL004VA](
[ID] [int] NOT NULL, 
[DATYEN] [varchar](18) NULL, 
[ZZRIDN] [varchar](8) NULL, 
[OQTIEF] [varchar](1) NULL, 
[OQMONE] [varchar](3) NULL, 
[ZZPONR] [varchar](3) NULL, 
[ZZNBRE] [varchar](15) NULL, 
[ZZPDSE] [varchar](22) NULL 
); 

CREATE TABLE [R_INTCOL004VA](
[ID] [int] NOT NULL, 
[DATYEN] [varchar](18) NULL, 
[ZZRIDN] [varchar](8) NULL, 
[OQTIEF] [varchar](1) NULL, 
[OQMONE] [varchar](3) NULL, 
[ZZPONR] [varchar](3) NULL, 
[ZZNBRE] [varchar](15) NULL, 
[ZZPDSE] [varchar](22) NULL 
); 

INSERT INTO INTCOL004VA VALUES 
('53671955', 'MC1141103006', '38565363', '1', '007', '010', '0', '0'), 
('53671956', 'MC1141103006', '38565363', '0', NULL, '020', '0', '0'), 
('53671957', 'MC1141103006', '38565363', '0', '007', '030', '1', '500'), 
('53671958', 'VT1141103010', '38565421', '1', '007', '050', '0', '0'), 
('53671959', 'VT1141103010', '38565421', '0', NULL, '100', '0', '0'), 
('53671960', 'ST1141103006', '38587542', '0', NULL, '010', '1', '500'), 
('53671961', 'ST1141103006', '38587542', '1', 'B01', '020', '5', '0'); 

INSERT INTO [R_INTCOL004VA] VALUES 
('53671955', 'MC1141103006', '38565363', '0', NULL, '010', '0', '0'), 
('53671956', 'MC1141103006', '38565363', '0', NULL, '020', '0', '0'), 
('53671957', 'MC1141103006', '38565363', '0', NULL, '030', '1', '500'), 
('53671960', 'ST1141103006', '38587542', '0', NULL, '010', '1', '500'), 
('53671961', 'ST1141103006', '38587542', '0', NULL, '020', '0', '0'), 
('53671958', 'VT1141103010', '38565421', '1', '007', '050', '0', '0'), 
('53671959', 'VT1141103010', '38565421', '1', '007', '100', '0', '0') 


SELECT 
    D.ID, 
    D.DATYEN, 
    D.ZZRIDN, 
    D.OQTIEF, 
    E.OQTIEF AS CORRECT_OQTIEF, 
    D.OQMONE, 
    E.OQMONE AS CORRECT_OQMONE, 
    D.ZZPONR, 
    D.ZZNBRE, 
    D.ZZPDSE 
FROM 
    INTCOL004VA AS D 
INNER JOIN 
    R_INTCOL004VA AS E ON D.ID = E.ID 

UPDATE 
    INTCOL004VA 
SET 
    OQTIEF = 0, 
    OQMONE = NULL 
FROM 
    INTCOL004VA AS A 
INNER JOIN 
    (SELECT 
     B.DATYEN, 
     B.ZZRIDN 
    FROM 
     INTCOL004VA AS B 
    GROUP BY 
     B.DATYEN, 
     B.ZZRIDN 
    HAVING 
     SUM(CAST(B.ZZNBRE AS INT)) > 0 
    ) AS C ON A.DATYEN = C.DATYEN AND A.ZZRIDN = C.ZZRIDN 


UPDATE 
    INTCOL004VA 
SET 
    OQTIEF = 1, 
    OQMONE = C.OQMONE 
FROM 
    INTCOL004VA AS A 
INNER JOIN 
    (SELECT 
     B.DATYEN, 
     B.ZZRIDN, 
     MAX(ISNULL(B.OQMONE,'')) AS OQMONE 
    FROM 
     INTCOL004VA AS B 
    GROUP BY 
     B.DATYEN, 
     B.ZZRIDN 
    HAVING 
     SUM(CAST(B.OQTIEF AS INT)) > 0 
    ) AS C ON A.DATYEN = C.DATYEN AND A.ZZRIDN = C.ZZRIDN 


SELECT 
    D.ID, 
    D.DATYEN, 
    D.ZZRIDN, 
    D.OQTIEF, 
    E.OQTIEF AS CORRECT_OQTIEF, 
    D.OQMONE, 
    E.OQMONE AS CORRECT_OQMONE, 
    D.ZZPONR, 
    D.ZZNBRE, 
    D.ZZPDSE 
FROM 
    INTCOL004VA AS D 
INNER JOIN 
    R_INTCOL004VA AS E ON D.ID = E.ID 

有時只是把它分解成更小的塊是更容易的方法來解決問題。

+0

不可能在一個查詢中? :( – cerede2000 2014-11-05 10:16:15

+0

我確信它可以在一個動作中完成,但是這個問題會變得複雜和可讀性,不僅僅是爲了你自己,而且還是下一個開發者必須在你後面維護這個腳本。在這兩種力量之間,通常我們會傾向於稍微慢一些的代碼,這些代碼更容易維護,更容易驗證。準確性比剃鬚和額外的3ms更重要。據說我確實很享受能夠編寫一個超級複雜的查詢因爲這是一個挑戰,我認爲我可以做到這一點,但是當我這樣做時,我的開發人員會討厭我。 – 2014-11-05 14:57:44

+0

@BenjaminCEREDE你總是可以將所有事務都包裝在一個事務中 – Horaciux 2014-11-05 15:45:51