Сложный запрос обновления SQL фильтрует только отдельные значения

#mysql #sql #count #sql-update #inner-join

#mysql #sql #количество #sql-обновление #внутреннее соединение

Вопрос:

У меня есть 3 таблицы со следующими столбцами.

  1. Таблица: A со столбцом: newColumnTyp1, typ2
  2. Таблица: B со столбцом: typ2, tableC_id_fk
  3. Таблица: C со столбцом: id, typ1

Я хотел обновить значения в A.newColumnTyp1 из C.typ1, следуя логике:

  1. если A.typ2=B.typ2 и B.tableC_id_fk=C.id
  2. значения должны быть разными, если какое-либо из приведенных выше условий дает несколько результатов, то их следует игнорировать. Например, A.typ2= B.typ2 может дать множественный результат, в этом случае его следует игнорировать.

Редактировать:

  1. значения должны быть разными, если какое-либо из приведенных выше условий дает несколько результатов, тогда принимайте только одно значение и игнорируйте rest. Например, A.typ2= B.typ2 может дать множественный результат, в этом случае просто примите любое одно значение и игнорируйте rest, потому что все результаты из A.typ2=B.typ2 будут иметь одинаковый B.tableC_id_fk.

Я пробовал:

 SELECT DISTINCT C.typ1, B.typ2
FROM C
  LEFT JOIN B ON C.id = B.tableC_id_fk
  LEFT JOIN A ON B.typ2= A.typ2
  

это дает мне результат таблицы с двумя столбцами typ1, typ2
Моя логика заключалась в том, что затем я отфильтрую эту новую таблицу и сравню значение type2 с A.typ2 и обновлю A.newColumnTyp1
Я думал о чем-то подобном, но потерпел неудачу:

 update A set newColumnTyp1= (
SELECT C.typ1 from
SELECT DISTINCT C.typ1, B.typ2
FROM C
  LEFT JOIN B ON C.id = B.tableC_id_fk
  LEFT JOIN A ON B.typ2= A.type2 
where A.typ2=B.typ2);
  

Ответ №1:

Я имею в виду обновляемый CTE и оконные функции:

 with cte as (
    select a.newColumnTyp1, c.typ1, count(*) over(partition by a.typ2) cnt
    from a
    inner join b on b.type2 = a.typ2
    inner join c on c.id = b.tableC_id_fk
)
update cte
set newColumnTyp1 = typ1
where cnt > 1
  

Обновление: если столбцы имеют одинаковое имя, то псевдоним одного из них:

 with cte as (
    select a.typ1, c.typ1 typ1c, count(*) over(partition by a.typ2) cnt
    from a
    inner join b on b.type2 = a.typ2
    inner join c on c.id = b.tableC_id_fk
)
update cte
set typ1 = typ1c
where cnt > 1
  

Комментарии:

1. @StackDummy: ок. Смотрите мой pdate

2. Еще раз спасибо, я попробовал с помощью: с cte как (выберите.newColumnTyp1 как atyp1, c.typ1 как ctyp1, подсчитайте (*) над (разделением на.typ2) cnt из внутреннего соединения b на b.type2 = a.typ2 внутреннее соединение c на c.id = б.tableC_id_fk ) обновление cte set atyp1= btyp1 где cnt > 1

Ответ №2:

Я думаю, что я бы подошел к этому как:

 update a
    set newColumnTyp1 = bc.min_typ1
    from (select b.typ2, min(c.typ1) as min_typ1, max(c.typ1) as max_typ1
          from b join
               c
               on b.tableC_id_fk = c.id
          group by b.type2
         ) bc
     where bc.typ2 = a.typ2 and
           bc.min_typ1 = bc.max_typ1;
  

Подзапрос определяет typ1 , всегда ли он один и тот же. Если это так, он используется для обновления.

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