为啥我不能在 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_idv.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却可以?

为啥聚集函数不能出现在where子句中

为啥sql查询语句中的count(*)等聚合函数可以放在having后面,而不能放在where后面?

为啥要在 SQL 中使用 WHERE 1=0 语句?

为啥我不能像使用列表一样过滤 IQueryable?