我遇到了SQL问题。我查看了遍历stackoverflow并没有找到解决我问题的方法。我有一个insert语句,可以从不同的表中选择" where"声明它看起来在不同的表等。
有一个问题,其中一个子查询返回多个值。我需要实现的目标:在指定的表中将插入两个(或更多,取决于它将返回多少)行。
错误示例,我正在努力实现的目标:
create database tst;
/*1*/
create table person_account_table(
per_id varchar(50),
acct_id varchar(50)
);
insert into person_account_table(per_id, acct_id)
values('123','123');
insert into person_account_table(per_id, acct_id)
values('321','321');
insert into person_account_table(per_id, acct_id)
values('321','363');
/*1*/
/*2*/
create table person_id_table(
per_id varchar(50),
per_nbr varchar(50),
type_cd varchar(50)
);
insert into person_id_table(per_id, per_nbr, type_cd)
values ('123', 'zx32', 'good');
insert into person_id_table(per_id, per_nbr, type_cd)
values ('123', '32zx', 'pklx');
insert into person_id_table(per_id, per_nbr, type_cd)
values ('321', '35xcz', 'good');
insert into person_id_table(per_id, per_nbr, type_cd)
values ('321', 'fes235', 'pklx');
/*2*/
/*3*/
create table table_one(
au_id varchar(50),
type_cd varchar(50),
acct_id varchar(50)
);
insert into table_one(au_id, type_cd, acct_id)
values('1', 'e-pg', '321');
insert into table_one(au_id, type_cd, acct_id)
values('2', 'e-pg', '363');
insert into table_one(au_id, type_cd, acct_id)
values('3', 'e-pg', '123');
/*3*/
/*4*/
create table table_two(
per_nbr varchar(50),
ob_nbr varchar(50),
flag varchar(1)
);
insert into table_two(per_nbr, ob_nbr, flag)
values('zx32', 'dfas', 'N');
insert into table_two(per_nbr, ob_nbr, flag)
values('zx32', 'dfsvgd', 'P');
insert into table_two(per_nbr, ob_nbr, flag)
values('zx32', 'dsfds', 'N');
insert into table_two(per_nbr, ob_nbr, flag)
values('zx32', 'sdfdsf', 'P');
insert into table_two(per_nbr, ob_nbr, flag)
values('35xcz', 'dhf', 'N');
insert into table_two(per_nbr, ob_nbr, flag)
values('35xcz', 'tes', 'N');
insert into table_two(per_nbr, ob_nbr, flag)
values('35xcz', 'dfgdf', 'P');
insert into table_two(per_nbr, ob_nbr, flag)
values('35xcz', 'ehdhs', 'P');
/*4*/
-- table in which I want to inser data
create table result_table(
obj_nbr varchar(50),
au_id varchar(50)
);
插入声明:
insert into result_table (obj_nbr, au_id)
select tt.ob_nbr,
(
select to1.au_id
from table_one to1
where to1.acct_id in
(
select pat.acct_id
from person_account_table pat
where pat.per_id in
(
select pit.per_id
from person_id_table pit
where pit.per_nbr = tt.per_nbr and
pit.type_cd in ('good')
)
)
)
from table_two tt
where tt.flag = 'N';
我得到结果:子查询返回超过1行
在这个特定示例中,我收到此错误,因为per_id = 321有两个不同的帐户。每个帐户都从table_one获取它自己的au_id。 如何重写此查询,它不会崩溃,但在结果表中插入两行?
答案 0 :(得分:2)
以下是使用内部联接的解决方案。它returns the same result as @Dimitry但不使用SQL89语法。 (很老)
insert into result_table (obj_nbr, au_id)
select
tt.ob_nbr,
to1.au_id
from
table_one to1
inner join person_account_table pat on to1.acct_id = pat.acct_id
inner join person_id_table pit on pat.per_id = pit.per_id
inner join table_two tt on tt.per_nbr = person_id_table.per_nbr
where
pit.type_cd in ('good')
and tt.flag = 'N';
答案 1 :(得分:1)
您的查询可以转到此:
insert into result_table (obj_nbr, au_id)
select tt.ob_nbr,
to1.au_id
from person_account_table pat,
person_id_table pit,
table_one to1,
table_two tt
where pat.per_id = pit.per_id
and pit.per_nbr = tt.per_nbr
and to1.acct_id = pat.acct_id
and pit.type_cd in ('good')
and tt.flag = 'N';
但它返回6行(检查sqlfiddle.com)。
修改强>
正如Dave Costa在评论中指出的那样,我的查询可以在重复的情况下产生更多的行。我没有研究你的测试数据,因为它非常复杂,但你有很多行在列中有重复,用于连接表。这可能是你的错误和我的冗余行的原因。所以它可以是两种可能性之一:您的查询应该真正返回6行,或者您需要更多条件来指定您需要的内容。在第二种情况下,它将取决于您的数据的含义和期望的结果。