为啥我不能在 INSERT 语句中使用 WHERE 子句进一步压缩我的查询?
Posted
技术标签:
【中文标题】为啥我不能在 INSERT 语句中使用 WHERE 子句进一步压缩我的查询?【英文标题】:Why can't I further condense my query with WHERE clause in INSERT statement?为什么我不能在 INSERT 语句中使用 WHERE 子句进一步压缩我的查询? 【发布时间】:2020-01-04 00:49:27 【问题描述】:忽略问号(对于 Java 准备语句),但此查询用于跟踪谁正在查看特定报销,并在当前查看时将其姓名存储在“whose_hands”字段中。如果他们的用户名以及他们查看过的 reimb_id 位于查看的表中,则他们无法再次填充 who_hands 字段。这样做的目的是在不重复查看者的情况下将报销形式传递给用户链。它不允许我使用最后的 WHERE 子句,因为我可以将用户名插入到特定的报销记录中。有解决办法吗?
INSERT INTO reimbursements(whose_hands)
VALUES(
select username
from users u
join department d on u.department_id=d.department_id
WHERE position = 'DeptHead'
AND NOT EXISTS(
SELECT username,reimb_id
FROM viewed v
WHERE v.username = u.username
and reimb_id=?)
where reimb_id = ?));
【问题讨论】:
那么您是要在报销表中插入新记录还是更新表的某一列值? 样本数据和期望的结果将阐明您想要做什么。 “为什么我不能在 INSERT 语句中使用 WHERE 子句进一步压缩我的查询?” 因为 SELECT 语句只能有 一个 WHERE子句,你有 两个。尝试使用 AND 代替。虽然你也会发现 INSERT ... VALUES (SELECT....) 是错误的,它应该只是 INSERT ... SELECT 【参考方案1】:您的语法不正确。应该是——
INSERT INTO reimbursements(whose_hands)
select username
from users u
join department d on u.department_id=d.department_id
WHERE position = 'DeptHead'
AND NOT EXISTS(SELECT username
FROM viewed v
WHERE v.username = u.username
and reimb_id=?);
【讨论】:
这仍然不能解决我需要获取 reimb_id 才能知道我想将用户名存储在哪条记录中的问题。 我没有正确理解您的问题。我只是试图修复查询。请发布一些示例数据和预期结果。 我想将已查看并批准表单的用户存储在新表(已查看)中,并且仅将“whose_hands”字段设置为同一部门尚未查看的用户.我通过在查看的表中存储他们的用户名和他们已批准的 reimb_id 并检查以确保没有人多次查看特定的报销来做到这一点。我遇到的唯一问题是我无法在 Insert 语句之外添加额外的 WHERE 子句,以让查询知道我要根据 reimb_id 插入用户的记录。 @kobs24 所有这些额外的细节都有帮助,但最好是在问题本身而不是在 cmets 的答案中。 (而且我不知道您所说的压缩查询是什么意思。)【参考方案2】:在 SELECT 语句中不能有两个 WHERE
子句。在这种情况下,我建议您将多余的 WHERE
替换为 AND
:
INSERT INTO reimbursements(whose_hands)
VALUES (select username
from users u
join department d
on u.department_id = d.department_id
WHERE position = 'DeptHead' AND
reimb_id = ? AND
NOT EXISTS(SELECT username,reimb_id
FROM viewed v
WHERE v.username = u.username and
v.reimb_id = u.reimb_id))
在最里面的子查询中,您应该将reimb_id=?
替换为v.reimb_id=u.reimb_id
或v.reimb_id = d.reimb_id
,但我不知道您的哪个表中有reimb_id
字段。我在上面的示例中显示了u.reimb_id
,但如果这不正确,请使用正确的表别名。
【讨论】:
【参考方案3】:这就是我想出的。我意识到我需要更新“whose_hands”字段,而不是插入新值:
create or replace PROCEDURE approve(department2 varchar2, reimb_id2 number)
IS
BEGIN
INSERT INTO viewed
VALUES(review_val.nextval,(SELECT whose_hands FROM reimbursements WHERE reimb_id = reimb_id2),
(SELECT reimb_id FROM reimbursements WHERE reimb_id = reimb_id2)); /* Stores current whose_hands and reimb_id in viewed table so they can't view again */
UPDATE reimbursements
set whose_hands=
(select username
from users u
join department d on u.department_id=d.department_id
WHERE position = 'DeptHead' AND department= department2
AND NOT EXISTS(SELECT username
FROM viewed v
WHERE v.username = u.username
and reimb_id=reimb_id2)) WHERE reimb_id = reimb_id2;
end;
感谢所有帮助。
【讨论】:
以上是关于为啥我不能在 INSERT 语句中使用 WHERE 子句进一步压缩我的查询?的主要内容,如果未能解决你的问题,请参考以下文章
为啥“WHERE”查询不能在 php 中使用 SQLITE [重复]
SQL语句中,为啥where子句不能使用列别名,而order by却可以?