Sql 如何使用两个表执行更新

Sql 如何使用两个表执行更新,sql,postgresql,join,Sql,Postgresql,Join,我想通过连接两个不同的表来执行更新操作 My tables are : dim_sess name role 20111012133513aaa123 20110908072611aaa121 20111002210235bbb853 20120113113353bbbl971 稍后将更新“角色”列 另一张桌子是 employeerol

我想通过连接两个不同的表来执行更新操作

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中的“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函数来连接它们,以匹配结果。但这似乎是一个糟糕的解决方案。我想知道是否有其他方法连接这两个表。

我看到的解决您问题的唯一其他方法是,您的
dim\u sess
表中有一个直接相关的
username
数据字段。您可以使用一个持久化的计算机列,然后对该列执行
JOIN
。因此,新的
dim_sess
表定义可能如下所示:

create table dim_sess
(
    name varchar(100),
    username as (SUBSTRING(name,15,7)) persisted,
    role varchar(100)
)
go

对于您的问题,我看到的唯一其他解决方案是,在
用户名的
维度表中有一个直接相关的数据字段。您可以使用一个持久化的计算机列,然后对该列执行
JOIN
。因此,新的
dim_sess
表定义可能如下所示:

create table dim_sess
(
    name varchar(100),
    username as (SUBSTRING(name,15,7)) persisted,
    role varchar(100)
)
go
试试这个:

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,因此语法可能有点不同。

尝试以下方法:

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,因此语法可能会有所不同。

您可以使用employeerole进行相关更新,并使用子查询从dim_sess.name及其ctid(=唯一行标识符)提取字段,以连接回要更新的行。通过添加FROM子句,然后添加其他表或子查询,可以在PG中编写相关更新。 它还有一个regexp_matches函数,比所有那些substring()调用都简单。它返回一个数组,其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

您可以使用employeerole执行相关更新,并使用子查询从dim_sess.name及其ctid(=唯一行标识符)提取字段,以连接回要更新的行。通过添加FROM子句,然后添加其他表或子查询,可以在PG中编写相关更新。 它还有一个regexp_matches函数,比所有那些substring()调用都简单。它返回一个数组,其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

为类似名称添加列为类似名称添加列为类似名称添加列,但我还需要与startdate核对。同一用户可以在不同的日期扮演不同的角色。@Rohita使用您的
JOIN
。但我还需要与startdate核对。同一用户可以在不同的日期扮演不同的角色。@Rohita使用您的
JOIN
进行核对是的,我正在使用PostgresSQL。我得到了相同的错误:“错误:一个用作表达式的子查询返回了多行”如果您得到了这个错误,那么它表明您的EMPLOYEEROLE表中有重复的条目。尝试运行查询
按用户名从EMPLOYEEROLE组中选择USERNAME、STARTDATE、count(*),STARTDATE的count(*)大于1以查找它们。我猜这种类型的重复项是不允许的,但如果它们是,那么您可以将我的子查询更改为
select min(ER.ROLE)
,例如。是的,我正在使用PostgresSQL。我得到了相同的错误:“错误:一个用作表达式的子查询返回了多行”如果您得到了这个错误,那么它表明您的EMPLOYEEROLE表中有重复的条目。尝试运行查询
按用户名从EMPLOYEEROLE组中选择USERNAME、STARTDATE、count(*),STARTDATE的count(*)大于1以查找它们。我猜这种类型的重复项是不允许的,但是如果它们是,那么您可以将我的子查询更改为
selectmin(ER.ROLE)