循环记录并根据条件更新数据库
Posted
技术标签:
【中文标题】循环记录并根据条件更新数据库【英文标题】:Loop through records and update database on conditions 【发布时间】:2016-12-30 19:50:04 【问题描述】:我有一张桌子Person
:
其中ID
是主键,Male
是男性总数,Female
是女性总数,Person_ID
列固定为4,所以男性+女性的最大数量是4 (我们不必对此进行验证)。
我需要将Yes
或No
的最后一列Is_Valid
值插入/更新,以确定记录是否有效。
逻辑如下:例如男性和女性的总数为 3,则必须有 3 个人员 ID,或者如果男性和女性的总数为 2,则必须有 2 个人员 ID 数据。
所以记录 ID 3 和 4 是无效的,因为记录 3 - 有 2 人(1 男 1 女)但只有 1 人 ID,记录 4 有 1 人(1 女)但没有人ID 数据。
我需要在 c# 代码中以编程方式执行此操作,但首先我想知道可以解决此问题的查询?
我一直在想的逻辑是:
遍历每一行 得到男性 + 女性的总和 = a 以某种方式计算非空人员 ID 单元格 = b 如果 a == b 则插入 YES,否则插入 NO我不知道如何编写查询(或存储过程),我想它会有点复杂。任何帮助将不胜感激。
【问题讨论】:
personid列是固定4列吗? @ShakeerMirza 是的 我认为如果您对数据进行规范化会更好,这样您就可以拥有一个主表和一个辅助表,而不是四个 Person_Id 列,其中包含以下列:Id、fkey to primary表,男(位),女(位),Person_Id。然后所有四个(或许多)记录将指向主表中的同一记录。像这样固定所有值后,当您决定需要五个 Person_Id 时,您必须同时修改架构和查询。否则,Long 的答案应该有效。 【参考方案1】:UPDATE TABLE
SET Is_Valid = CASE WHEN (
Case when Person1_ID != '' or Person1_ID IS NOT NULL Then 1 else 0 end +
Case when Person2_ID != '' or Person2_ID IS NOT NULL Then 1 else 0 end +
Case when Person3_ID != '' or Person3_ID IS NOT NULL Then 1 else 0 end +
Case when Person4_ID != '' or Person4_ID IS NOT NULL Then 1 else 0 end ) != Male + Female THEN 'NO' ELSE 'YES' END
【讨论】:
试试这个查询,不确定它是否工作正常,因为我没有你的表,如果有任何运行时问题,请更新我 -【参考方案2】:CREATE TABLE #Demo
(
id integer not null primary key,
male integer NULL,
female integer NULL,
PersonId_1 integer null,
PersonId_2 integer null,
PersonId_3 integer null,
PersonId_4 integer null,
IsValid bit not null
);
insert into #Demo
(id, male, female, PersonId_1,PersonId_2,PersonId_3,PersonId_4,IsValid)
values
(1,1,1,2,2,null,null,0)
update #Demo
set IsValid = 1
where (#Demo.male + #Demo.female) =
(case when #Demo.PersonId_1 IS NOT NULL Then 1 Else 0 end)+
(case when #Demo.PersonId_2 IS NOT NULL Then 1 Else 0 end)+
(case when #Demo.PersonId_3 IS NOT NULL Then 1 Else 0 end)+
(case when #Demo.PersonId_4 IS NOT NULL Then 1 Else 0 end)
select * from #Demo
【讨论】:
【参考方案3】:您可以为此运行更新语句,而不必遍历它。或者您可以将 is_valid 设为计算列。
DECLARE @test TABLE (
id INT IDENTITY(1,1)
,male INT
,female INT
,person1_id INT
,person2_id INT
,person3_id INT
,person4_id INT
,is_valid AS CASE
WHEN (male + female = 1 AND person1_id IS NOT NULL AND person2_id IS NULL AND person3_id IS NULL AND person4_id IS NULL)
OR (male + female = 2 AND person1_id IS NOT NULL AND person2_id IS NOT NULL AND person3_id IS NULL AND person4_id IS NULL)
OR (male + female = 3 AND person1_id IS NOT NULL AND person2_id IS NOT NULL AND person3_id IS NULL AND person4_id IS NULL)
OR (male + female = 4 AND person1_id IS NOT NULL AND person2_id IS NOT NULL AND person3_id IS NOT NULL AND person4_id IS NULL)
THEN 1
ELSE 0
END
)
INSERT @test (male,female,person1_id,person2_id,person3_id,person4_id)
VALUES
(1,1,200,700,NULL,NULL)
,(2,0,205,210,NULL,NULL)
,(1,1,240,NULL,NULL,NULL)
,(0,1,NULL,NULL,NULL,NULL)
SELECT * FROM @test
【讨论】:
【参考方案4】:添加Male + Female
列值并将它们与具有非空值或空值的列数进行比较。如果它们相等,则将Is_Valid
设置为 1,否则将其设置为 0。
update p
set Is_Valid =
case
when Male + Female = (iif(Isnull(Person1_ID, '') = '', 0, 1) + iif(Isnull(Person2_ID, '') = '', 0, 1) +
iif(Isnull(Person3_ID, '') = '', 0, 1) + iif(Isnull(Person4_ID, '') = '', 0, 1)) then 'YES'
else 'NO'
end
from Person p
只是为了澄清下面的代码检查该列是否具有空值并将其设为空,然后检查它是否为空,如果是则将其设为 0,否则将其设为 1。这是针对每一列完成的:
iif(Isnull(Person1_ID, '') = '', 0, 1)
您也可以这样做以更加小心并检查空格:
iif(Isnull(rtrim(ltrim(Person1_ID))), '') = '', 0, 1)
【讨论】:
【参考方案5】:无需循环
;WITH CTE
AS (
SELECT id
,CASE
WHEN (male + female) = isnull(personid_1 / personid_1, 0)
+ isnull(personid_2 / personid_2, 0)
+ isnull(personid_3 / personid_3, 0)
+ isnull(personid_4 / personid_4, 0)
THEN 'Yes'
ELSE 'No'
END AS valid
FROM PERSON
)
UPDATE PERSON
SET IS_VALID = CTE.VALID
FROM CTE
WHERE PERSON.ID = CTE.ID
【讨论】:
以上是关于循环记录并根据条件更新数据库的主要内容,如果未能解决你的问题,请参考以下文章
Spring-batch - 比较来自 csv 的数据并相应地更新 Salesforce 中的记录