Как выполнить обновление, используя две таблицы - PullRequest
2 голосов
/ 21 января 2012

Я хочу выполнить операцию обновления, объединив две разные таблицы.

My tables are :

dim_sess

name                                        role
20111012133513aaa123                    
20110908072611aaa121        
20111002210235bbb853
20120113113353bbbl971           

Столбец роли обновляется позже.

, а другая таблица -

employeerole
username           role             thedate
aaa         technician      2011-10-12 13:35:13
aaa         technician      2011-09-08 07:26:11
bbb         day guard       2011-10-02 21:02:35
bbb         day guard       2012-01-13 11:33:53
bbb         night guard     2012-01-13 21:30:00

Я хочу обновить роль в таблице dim_sess в зависимости от имени пользователя и начальной даты.Один и тот же пользователь может играть разную роль в разные даты.В двух таблицах нет общего столбца, и единственный столбец для выполнения соединения - это «имя» в dim_sess.

Я пишу следующий запрос для обновления таблицы dim_ses.

 UPDATE dim_sess
SET role = (SELECT employeerole.role FROM employeerole
WHERE SUBSTRING(dim_sess.name,15,7) = employeerole.username
AND SUBSTRING(dim_sess.name,1,14) = (TEXTCAT( TEXTCAT(TEXTCAT(SUBSTRING(thedate,1,4), SUBSTRING(thedate,6,2)) , TEXTCAT(SUBSTRING(thedate,9,2), SUBSTRING(thedate,12,2)) ), TEXTCAT(      SUBSTRING(thedate,15,2), SUBSTRING(thedate,18,2)))))
WHERE SUBSTRING(dim_sess.name,1,21) = (SELECT TEXTCAT((TEXTCAT(TEXTCAT(TEXTCAT(SUBSTRING(thedate,1,4), SUBSTRING(thedate,6,2)) , TEXTCAT(SUBSTRING(thedate,9,2), SUBSTRING(thedate,12,2))), TEXTCAT(SUBSTRING(thedate,15,2), SUBSTRING(thedate,18,2)))) , employeerole.username) AS session FROM employeerole);

The error message I get is:
ERROR:  more than one row returned by a subquery used as an expression

Поскольку между двумя таблицами нет общего столбца, я пытаюсь объединить их, используя функцию подстроки для сопоставления результатов.Но это кажется плохим решением.Мне было интересно, есть ли другой способ объединить эти две таблицы.

Ответы [ 3 ]

0 голосов
/ 21 января 2012

Попробуйте это:

update DIM_SESS DS
   set ROLE =
         (select ER.ROLE
            from EMPLOYEEROLE ER
           where substr(
                   DS.NAME
                  ,1
                  ,length(to_char(STARTDATE, 'yyyymmddhh24miss') || USERNAME)) like
                   to_char(STARTDATE, 'yyyymmddhh24miss') || USERNAME);

Я проверял это в Oracle, но я думаю, что вы, возможно, используете PostgreSQL, поэтому синтаксис может немного отличаться.

0 голосов
/ 22 января 2012

Вы можете выполнить коррелированное обновление, используя employeeerole и подзапрос, извлекающий поля из dim_sess.name и их ctid (= уникальный идентификатор строки), чтобы присоединиться к строкам для обновления. Связанные обновления можно записать в PG, добавив предложение FROM, за которым следуют другие таблицы или подзапросы. Также он имеет функцию regexp_matches, которая делает его проще, чем все эти вызовы substrings (). Он возвращает массив, чьи 1-> N элементов являются захваченными подстроками.

Кодовое предложение:

UPDATE dim_sess d SET role=e.role
FROM employeerole e,
(SELECT t[1] as f1, t[2] as f2, t[3] as f3, i  from
 (select ctid as i, regexp_matches(name, E'^(\\d{14})([a-z]+)(\\d+)') AS t from dim_sess) s1
) s2
WHERE d.ctid=s2.i
AND to_char(e.thedate,'yyyymmddHH24MISS')=f1
AND e.username=f2
0 голосов
/ 21 января 2012

Единственное другое решение, которое я вижу для вашей проблемы, состоит в том, что у вас есть прямо коррелированное поле данных в таблице dim_sess для username.Вы можете использовать постоянный компьютерный столбец, а затем сделать JOIN для этого столбца.Таким образом, ваше новое определение таблицы dim_sess может выглядеть примерно так:

create table dim_sess
(
    name varchar(100),
    username as (SUBSTRING(name,15,7)) persisted,
    role varchar(100)
)
go
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...