Обновление нескольких записей на основе 1 записи, соответствующей критериям - PullRequest
0 голосов
/ 29 октября 2019

Я пытаюсь выбрать все записи из набора данных, где 1 из записей соответствует критерию. У меня есть таблица данных, которые содержат часы, отработанные человеком в день. Мне нужно выбрать все записи для человека за эту неделю, если для одной записи в течение этой недели флаг 'logged' установлен на 'N'. Вот пример данных:

t_hours:

Name  Week  Weekday  Hours  Logged
===============================
Jim   1     Mon      8       Y
Jim   1     Wed      8       Y
Jim   1     Fri      8       Y
Jim   2     Mon      8       Y
Jim   2     Wed      8       Y
Bill  1     Mon      8       N
Bill  1     Tue      8       Y
Bill  1     Wed      8       Y
Bill  1     Thu      8       Y
Bill  2     Mon      8       Y
Bill  2     Tue      8       Y

Я хочу написать запрос, который обновит все записи для рабочей недели людей до Logged = 'N', если у них есть один деньгде Logged = 'N'. Но я не могу понять, как даже выбрать записи. Вот записи, которые я хочу обновить:

Name  Week  Weekday  Hours  Logged
===============================
Bill  1     Mon      8       N
Bill  1     Tue      8       Y
Bill  1     Wed      8       Y
Bill  1     Thu      8       Y

Я пробовал обычный выбор, но не могу понять, как иметь два коррелированных подзапроса в предложении where:

SELECT * FROM t_hours
WHERE (Name = (SELECT t1.Name FROM t_hours t1 
               where t1.Name = t2.Name and t1.Week = t2.Week and 
               t1.Logged = 'N') and
       Week = (SELECT t2.Week FROM t_hours t2 
               where t1.Name = t2.Name and t1.Week = t2.Week and 
               t2.Logged = 'N')

но это не работает, любая помощь очень ценится.

Ответы [ 4 ]

1 голос
/ 29 октября 2019

Вы можете использовать обновляемый CTE:

with toupdate as (
      select t.*,
             min(logged) over (partition by name, week) as min_logged
      from t
     )
update toupdate
    set logged = min_logged
    where min_logged = 'N' and min_logged <> logged;

Выражение min(logged) вернет 'N', если любое из значений logged равно 'N' (а остальные, если они есть * 1008)*) на человека / неделю.

0 голосов
/ 29 октября 2019

Это то, что вы хотите?

   Update table set Logged='N' where
      Exists (Select 1 from(Select 
        Name,Workweek group by Name, 
       Workweek having count(Logged='N')
        >=1)t1 where Name=t1.name and  
         Workweek=t1.Workweek) 
0 голосов
/ 29 октября 2019

Возвращаемые данные:

 SELECT *
FROM   t_hours t1
WHERE  EXISTS (SELECT 1
               FROM   t_hours t2
               WHERE  t1.NAME = t2.NAME
                      AND t1.week = t2.week
                      AND t2.logged = 'N');  

Обновление данных:

 UPDATE t_hours
SET    logged = 'N'
WHERE  EXISTS (SELECT 1
               FROM   t_hours t2
               WHERE  t1.NAME = t2.NAME
                      AND t1.week = t2.week
                      AND t2.logged = 'N');  

Если набор данных достаточно большой, вы можете сгруппировать по имени, неделе и типу журнала.

0 голосов
/ 29 октября 2019

попробуйте, как показано ниже, используя

select t1.* from table_name t1
where exists( select 1 from table_name t2 where t1.week=t2.week
                                          and t2.logged='N' and t1.name=t2.name
             )
...