部分SQL Server数据库实体是:
这种结构的逻辑是:
最佳理解的一个小例子:
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
更新
此查询需要将所有实体中保存的计数器数据与查询计算值进行比较,并在将来修复这些值。
对任何帮助都很乐意。
答案 0 :(得分: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
假设:数据是干净的,如上所述,如果表格很大,则会正确设置索引,不会出现其他意料之外的差异。