Mam następującą tabelę:

EmployeeId FirstName LastName       CurrentRecord DepartmentId UpdatedDate
50         Alain     Xavier         0             10           NULL
50         Alain     Xavier         0             15           NULL
50         Alain     Xavier Dupont  1             20           NULL
55         Nathalie  BUC            0             346          NULL
55         Nathalie  BUC Clement    1             346          NULL

Chcę zaktualizować wszystkie nazwiska na podstawie aktualnych dla każdego pracownika, jak poniżej, a UpdatedDate pobiera aktualną datę modyfikacji:

EmployeeId FirstName LastName       CurrentRecord DepartmentId UpdatedDate
50         Alain     Xavier Dupont  0             10           01/04/2020
50         Alain     Xavier Dupont  0             15           01/04/2020
50         Alain     Xavier Dupont  1             20           01/04/2020
55         Nathalie  BUC Clement    0             346          01/04/2020
55         Nathalie  BUC Clement    1             346          01/04/2020

Jak uzyskać łączenie cykliczne w klauzuli aktualizacji?

0
mohamed-mhiri 1 kwiecień 2020, 22:51

3 odpowiedzi

SQL Fiddle

Konfiguracja schematu programu SQL Server 2017 :

CREATE TABLE Employee (EmployeeId int, FirstName varchar(255), Lastname varchar(255),CurrentRecord bit
                       ,Department int,UpdateDate date)
INSERT INTO Employee(EmployeeId,FirstName,Lastname,CurrentRecord,Department,UpdateDate) VALUES (50,'Alain','Xavier',0,10,NULL),
                            (50,'Alain','Xavier',0,15,NULL),(50,'Alain','Xavier Dupont',1,20,NULL),
                            (45,'Nathalie','Buc',0,346,NULL),(45,'Nathalie','Buc Clement',1,346,NULL)

Zapytanie 1 :

UPDATE Employee
SET Employee.Lastname=E1.Lastname,UpdateDate=GETDATE()
FROM ( SELECT EmployeeId,Lastname FROM Employee WHERE CurrentRecord=1) AS E1
WHERE E1.EmployeeId=Employee.EmployeeId  

SELECT * FROM Employee

Wyniki :

0
Dale K 1 kwiecień 2020, 20:33

Możesz użyć do tego aktualizowanego CTE:

with toupdate as (
      select t.*,
             max(case when currentRecord = 1 then lastname end) over (partition by EmployeeId) as curr_lastname
      from t
     )
update toupdate
     set lastname = curr_lastname,
         updateddate = getdate()
     where curr_lastname <> lastname;

Jeśli masz kilka kolumn do zaktualizowania, może to być prostsze:

update t
    set lastname = curr.lastname,
        updateddate = getdate()
    from t join
         t curr
         on t.EmployeeId = curr.EmployeeId
    where curr.currentRecord = 1;
2
Gordon Linoff 1 kwiecień 2020, 19:54

Proste zapytanie podrzędne może sobie z tym poradzić:

update dbo.Employee set
  LastName = (select E1.LastName from dbo.Employee E1 where E1.CurrentRecord = 1 and E1.EmployeeId = Employee.EmployeeId)
  , UpdatedDate = current_timestamp
where CurrentRecord = 0;
1
Dale K 1 kwiecień 2020, 20:02