Как обновить без «ОШИБКА: более одной строки, возвращенной подзапросом, используемым в качестве выражения» - PullRequest
0 голосов
/ 15 октября 2018

Есть таблица с сгруппированными строками, которые имеют значение в одном столбце, но очень редко отличаются в другом столбце.

Мне нужно обновить ниже portfolio_id, если они не отличаютсяили, оптимально, по крайней мере, не отличаются в 90% случаев (хотя я понимаю, что это может быть сложно).

Структура таблицы

mytable1

table1id | parentgroup | portfolio_id
1        | 100         | 3
2        | 100         | 3
3        | 100         | 3
4        | 203         | 4
5        | 203         | 5
6        | 500         | 7

mytable2 вместе с намеченным результатом

count | parentgroup | portfolio_id
    3 |         100 | (trying to fill with a 3)
    2 |         203 | (shouldn't fill since half the dots are split within 2 portfolios)
    1 |         500 | (trying to fill with a 7)     

Мой запрос выглядит как

update mytable2 a
set portfolio_id = (select portfolio_id from mytable1 b
    where a.parentgroup = b.parentgroup)
where parentgroup is not null       

Но, очевидно, я получаю ошибку

Ошибка SQL [21000]: ОШИБКА: более одной строки, возвращенной подзапросом, использованным в качестве выражения

Как обойти это?

Ответы [ 3 ]

0 голосов
/ 15 октября 2018

Вот решение, которое обновляет mytable2, только если, по крайней мере, 90% всех portfolio_id с на parentgroup идентичны:

WITH grps_to_upd AS (
   SELECT parentgroup,
          portfolio_id
   FROM (SELECT parentgroup,
                portfolio_id,
                my_ct,
                sum(my_ct) OVER (PARTITION BY parentgroup) AS grp_ct
         FROM (SELECT parentgroup,
                      portfolio_id,
                      count(*) AS my_ct
               FROM mytable1
               GROUP BY parentgroup, portfolio_id
              ) AS grp1
        ) AS grp2
   WHERE my_ct::double precision / grp_ct::double precision >= 0.9
)
UPDATE mytable2
SET portfolio_id = grps_to_upd.portfolio_id
FROM grps_to_upd
WHERE mytable2.parentgroup = grps_to_upd.parentgroup;
0 голосов
/ 15 октября 2018

portfolio_id, а не поле массива, поэтому необходимо убедиться, что проекция SELECT должна возвращаться по одному за раз.

UPDATE mytable2 A
       SET portfolio_id = (SELECT portfolio_id FROM mytable1 B
                           WHERE A.parentgroup = B.parentgroup LIMIT 1)
       WHERE parentgroup IS NOT null 
0 голосов
/ 15 октября 2018

Вот один вариант, который использует CTE с обновлением соединения:

WITH cte AS (
    SELECT parentgroup, MAX(portfolio_id) AS portfolio_id
    FROM mytable1
    GROUP BY parentgroup
    HAVING MIN(portfolio_id) = MAX(portfolio_id)
)

UPDATE mytable2 a
SET portfolio_id = b.portfolio_id
FROM cte AS b
WHERE a.parentgroup = b.parentgroup;

Идея здесь заключается в том, что CTE находит для каждого parentgroup в первой таблице единственное значение portfolio_id, если существует единственное значение.Затем мы обновляем вторую таблицу, ориентируясь только на группы parentgroup, которые соответствуют чему-либо в CTE.

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