2014-09-29 22 views
1

部分是:我的SQL查詢的哪部分是錯誤的? SQL Server數據庫實體

  • 表格(ID,計數器)
  • 組(ID,Form_Id,計數器)
  • 字段(ID,分組ID,計數器)

這種結構的邏輯是:

  • 字段計數器可以是0或更高
  • 組計數器取決於該組中存在的字段的計數器:每個字段的計數器值大於0將組計數器遞增1
  • 組與表格之間存在相同的關係:form的計數器是該集團的計數器以高於0

最佳理解一個小例子:

Form A1 (Counter: 1) 
|-> Group BB1 (Counter: 2) 
    |-> Field CCC1 (Counter: 2) 
    |-> Field CCC2 (Counter: 1) 
|-> Group BB2 (Counter: 0) 
    |-> Field CCC3 (Counter: 0) 
    |-> Field CCC4 (Counter: 0) 
Form A2 
... 

某些字段包含我的查詢需要檢查無效值。但我無法用正確的方式寫出來。它的最新版本:

select distinct 
     cd.Id as [FormID], 
     sum (case when cd.Counter > 0 then 1 else 0 end) over (partition by cd.Id, gd.Id, fd.Id) as [FormSum], 
     cd.Counter as [FormVal], 

     gd.Id as [GroupID], 
     sum(case when gd.Counter > 0 then 1 else 0 end) over (partition by cd.Id, gd.Id, fd.Id) as [GroupSum], 
     gd.Counter as [GroupVal], 

     fd.Id as [FieldID], 
     --sum(case when fd.Counter > 0 then 1 else 0 end) over (partition by cd.Id, gd.Id) as [FieldSum], 
     fd.Counter as [FieldVal] 
    from FieldDatas fd 
    inner join GroupDatas gd on fd.GroupData_Id = gd.Id 
    inner join CrfDatas cd on gd.CrfData_Id = cd.Id 
    where cd.Id in 
    (
     -- some subquery 
    ) 
    order by cd.Id, gd.Id, fd.Id 

更新:
此查詢需要保存計數器的數據與查詢的計算值的所有實體比較,並在今後的修復這些值。

會很樂意爲您提供幫助。

+2

ddl和示例數據以及您希望查詢執行的操作的明確說明將大大幫助您獲得答案。 sqlfiddle.com是一個很好的開始。 – 2014-09-29 13:33:48

回答

1

您無法使用單個查詢更新兩個表的內容,因此我們最終得到兩個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 

假設:數據是乾淨的,如描述的那樣,指標設置是否正確,如果表很大,沒有其他意外的差異來向上。

+0

太好了,謝謝。非常清楚 – dotFive 2014-10-01 12:19:02