您無法使用單個查詢更新兩個表的內容,因此我們最終得到兩個UPDATE語句。接下來,在「上」之前修正「下」關係(組/字段)。步驟我把:
首先設置測試結構和數據:
-- Set up test tables
CREATE TABLE Forms
(Id int not null
,Counter int not null)
CREATE TABLE Groups
(Id int not null
,Form_id int not null
,Counter int not null)
CREATE TABLE Fields
(Id int not null
,Group_Id int not null
,Counter int not null)
-- Set up valid test data
DELETE Forms DELETE Groups DELETE Fields
INSERT Forms values
(1,1)
INSERT Groups values
(1,1,2)
,(2,1,0)
INSERT Fields values
(1,1,2)
,(2,1,1)
,(3,2,0)
,(4,2,0)
-- Set invalid Forms counter
DELETE Forms DELETE Groups DELETE Fields
INSERT Forms values
(1,2)
INSERT Groups values
(1,1,2)
,(2,1,0)
INSERT Fields values
(1,1,2)
,(2,1,1)
,(3,2,0)
,(4,2,0)
-- Set invalid Groups counter (both)
DELETE Forms DELETE Groups DELETE Fields
INSERT Forms values
(1,2)
INSERT Groups values
(1,1,0)
,(2,1,1)
INSERT Fields values
(1,1,2)
,(2,1,1)
,(3,2,0)
,(4,2,0)
-- Mondo invalid
DELETE Forms DELETE Groups DELETE Fields
INSERT Forms values
(1,0)
INSERT Groups values
(1,1,0)
,(2,1,1)
INSERT Fields values
(1,1,2)
,(2,1,1)
,(3,2,0)
,(4,2,0)
接下來,在「低」設置識別壞數據:
-- Detect bad data in Groups/Fields relationship
SELECT
gr.Id
,gr.Counter
,sum(case when fi.Counter <> 0 then 1 else 0 end) CalcValue
from Groups gr
left outer join Fields fi
on fi.Group_Id = gr.Id
group by
gr.Id
,gr.Counter
having sum(case when fi.Counter <> 0 then 1 else 0 end) <> gr.Counter
使用,作爲在更新的子查詢聲明:
-- Reset invalid Forms counters
UPDATE Groups
set Counter = xx.CalcValue
from Groups gr
inner join (-- Detect bad data in Groups/Fields relationship
select
gr.Id
,gr.Counter
,sum(case when fi.Counter <> 0 then 1 else 0 end) CalcValue
from Groups gr
left outer join Fields fi
on fi.Group_Id = gr.Id
group by
gr.Id
,gr.Counter
having sum(case when fi.Counter <> 0 then 1 else 0 end) <> gr.Counter) xx
on xx.Id = gr.Id
剪切,粘貼,重命名爲「上」集:
-- Detect bad data in Forms/Groups relationship
SELECT
fo.Id
,fo.Counter
,sum(case when gr.Counter <> 0 then 1 else 0 end) CalcValue
from Forms fo
left outer join Groups gr
on gr.Form_Id = fo.Id
group by
fo.Id
,fo.Counter
having sum(case when gr.Counter <> 0 then 1 else 0 end) <> fo.Counter
-- Reset invalid Forms counters
UPDATE Forms
set Counter = xx.CalcValue
from Forms fo
inner join (-- Detect bad data in Forms/Groups relationship
select
fo.Id
,fo.Counter
,sum(case when gr.Counter <> 0 then 1 else 0 end) CalcValue
from Forms fo
left outer join Groups gr
on gr.Form_Id = fo.Id
group by
fo.Id
,fo.Counter
having sum(case when gr.Counter <> 0 then 1 else 0 end) <> fo.Counter) xx
on xx.Id = fo.Id
只運行的順序更新和檢查結果:
SELECT * from Forms
SELECT * from Groups
SELECT * from Fields
假設:數據是乾淨的,如描述的那樣,指標設置是否正確,如果表很大,沒有其他意外的差異來向上。
ddl和示例數據以及您希望查詢執行的操作的明確說明將大大幫助您獲得答案。 sqlfiddle.com是一個很好的開始。 – 2014-09-29 13:33:48