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)
。