【问题标题】:Loop through records and update database on conditions循环记录并根据条件更新数据库
【发布时间】:2016-12-30 19:50:04
【问题描述】:

我有一张桌子Person

其中ID是主键,Male是男性总数,Female是女性总数,Person_ID列固定为4,所以男性+女性的最大数量是4 (我们不必对此进行验证)。

我需要将YesNo 的最后一列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 的答案应该有效。

标签: c# sql asp.net sql-server


【解决方案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
        

        【讨论】:

          猜你喜欢
          • 2010-10-08
          • 2012-12-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-09-14
          • 2015-09-20
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多