Как добавить номер строки в строку, если совпадение уже существует? - PullRequest
0 голосов
/ 29 августа 2018

У меня есть таблица пользователей с таким адресом электронной почты, как:

johnsmith@gmail.com

Я пытаюсь обновить реферальные коды пользователей с помощью удобочитаемой записи.

Я буду устанавливать этот код для первой части их электронного письма (до символа @) длиной не более 12 символов.

Если таких совпадений больше, чем ОДИН, например:

johnsmith@gmail.com и johnsmith@aol.com, тогда ко второму будет добавлено увеличение числа до конца.

Это должно привести к тому, что реферальные коды будут:

johnsmith и johnsmith1 и т. Д.

Прямо сейчас, даже если их всего два, я получаю:

johnsmith1 и johnsmith2.

В идеале, если есть только одна запись, не должно быть добавленного номера.

Как я могу это сделать?

Это то, что у меня сейчас есть:

  UPDATE auth.user_referral_codes
    SET referral_code = CONCAT((
      SELECT LEFT(LEFT(email, STRPOS(email, '@') - 1), 12)
      FROM auth.users
      WHERE id = auth.user_referral_codes.user_id
    ) , (
      SELECT row_number FROM (
        SELECT row_number()
        OVER (
          PARTITION BY (SELECT LEFT(LEFT(email, STRPOS(email, '@') - 1), 12))
        )
        FROM auth.users
        WHERE id = auth.user_referral_codes.user_id
      ) as row_number_subquery
    ));

Ответы [ 2 ]

0 голосов
/ 31 августа 2018

С небольшой настройкой ответа Гордона Линоффа это работает:

  UPDATE auth.user_referral_codes urc
    SET referral_code = (
      LEFT(LEFT(email, strpos(email, '@') - 1), 12)
      || (CASE WHEN seqnum > 1 THEN (seqnum-1)::TEXT ELSE '' END)
    )
    FROM (
      SELECT
        auth.users.*,
        row_number() OVER (
          PARTITION BY LEFT(LEFT(email, strpos(email, '@') - 1), 12)
          ORDER BY id
        ) AS seqnum
      FROM auth.users
    ) AS u
  WHERE urc.user_id = u.id;
0 голосов
/ 29 августа 2018

Ваш код кажется таким сложным:

update auth.user_referral_codes urc
    set referral_code = (left(left(email, strpos(email, '@') - 1), 12) ||
                         (case when seqnum > 1 then seqnum::text else '' end)
                        )
    from (select u.*,
                 row_number() over (partition by left(left(email, strpo(email, '@') - 1), 12) order by user_id) as seqnum
          from users u
         ) u
    where urc.user_id = u.id;

Postgres поддерживает предложение FROM в UPDATE с. Это очень полезно.

...