如何编写棘手的更新查询

时间:2011-07-08 21:33:33

标签: sql sql-server-2005

我需要更新表并使用以下规则将列(启用)设置为1

  1. 每个Employee_Guid必须有1(并且从不0或> 1)记录,启用设置为1。
  2. 它应该选择已删除的记录设置为0(应该只有一个或没有删除的记录设置为每个Employee_Guid为0)以将启用设置为1.
  3. 如果所有记录都已删除设置为1,则应使用具有最新Create_Date_Time
  4. 的记录
  5. 如果与创建日期时间相关,则可以将任何记录组的记录设置为1,但只能使用其中一个记录。
  6. 如果有多个记录已删除设置为0,我希望抛出一个错误,因为这是一个非法状态。

    这是我到目前为止所拥有的

    if(exists(select count(employee_guid) from Employees_M where deleted = 0 group by employee_guid having count(employee_guid) > 1))
        RAISERROR('More than one record has deleted set to 0')
    Update Employees_M set [ENABLE] = 0
    
    select * into #t from employees_m where deleted = 0
    insert into #t select * from employees_m where employee_guid not in (select employee_guid from #t) 
                                             and --fulfill rules 3 and 4
    
    Update Employees_M set [ENABLE] = 1
    where pk_guid in (select pk_guid from #t)
    

    这是表结构

    PK_Guid (primary key, uniuque, uniuqueidenitfier, not null)
    Employee_Guid (uniuqueidenitfier, not null)    
    Deleted (bit, not null)
    Enable (bit, not null)
    Create_Date_Time (datetime defaults to getdate(), not null)
    

    这不仅仅是一个“Show me teh codez”的问题。我想学习如何正确地做到这一点,所以也应该赞赏类似但不解决问题的链接或示例。

2 个答案:

答案 0 :(得分:1)

在这种情况下,通常可以使用row_number。其order by子句允许您分配优先级。在您的情况下,deleted ascCreate_Date desc似乎可以捕获要求。

以下是如何在更新查询中使用row_number的示例:

update  emp
set     enabled = case when rn = 1 then 1 else 0 end
from    (
        select  row_number() over (partition by employee_guid 
                                   order by deleted, Create_Date desc) as rn
        ,       *
        from    @employees
        ) emp

Full example at SE Data.

答案 1 :(得分:0)

难题。试试这个,我希望这有效。

if(exists(select 1 from Employees_M where deleted = 0  having count(employee_guid) > 1))
    RAISERROR('More than one record has deleted set to 0')

Update Employees_M E
set [ENABLE] = 1
WHERE EXISTS 
(
  SELECT 1 
  FROM Employees_M  
  WHERE E.employee_guid = employee_guid 
  AND (DELETED = 0 OR DELETED IS NULL)
) --SECOND POINT
OR EXISTS 
(
  SELECT 1 
  FROM Employees_M  
  WHERE E.employee_guid = employee_guid 
  AND ENABLE <> 1 -- 4 POINT 
  AND Create_Date_Time =  
  (
    SELECT DISTINCT(MAX(Create_Date_Time)) 
    FROM Employees_M 
    WHERE E.employee_guid = employee_guid 
  )
  HAVING COUNT(employee_guid) = SUM(deleted) --3 POINT
)