我想通过连接两个不同的表来执行更新操作。
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
我想根据用户名和startdate更新dim_sess表中的角色。同一用户可以在不同的日期拥有不同的角色。两个表中没有公共列,唯一要执行连接的列是dim_sess中的“name”。
我编写以下查询来更新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
由于两个表之间没有公共列,我尝试使用substring函数来匹配结果。但这似乎是一个糟糕的解决方案。我想知道是否有其他方法可以加入这两个表。
答案 0 :(得分:0)
我看到您问题的另一个解决方案是dim_sess
表中username
表中存在直接相关的数据字段。您可以使用持久计算机列,然后在该列上执行JOIN
。所以你的新dim_sess
表定义可能是这样的:
create table dim_sess
(
name varchar(100),
username as (SUBSTRING(name,15,7)) persisted,
role varchar(100)
)
go
答案 1 :(得分:0)
试试这个:
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,因此语法可能会略有不同。
答案 2 :(得分:0)
您可以使用employeerole和子查询进行相关更新,从子目录中提取dim_sess.name及其ctid(=唯一行标识符)中的字段以加入返回要更新的行。可以通过添加FROM子句后跟其他表或子查询在PG中写入相关更新。 它还有一个regexp_matches函数,比所有那些子串()调用更容易。它返回一个数组,其中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