为什么更新不能与内部联接一起使用?

发布于 2024-10-01 09:56:56 字数 1392 浏览 2 评论 0原文

这是我的表格的简化版本。

CREATE TABLE TBLAGENT(AGENTID NUMBER, NUMBERSENT NUMBER, AGENTNAME VARCHAR2(100));
INSERT INTO TBLAGENT VALUES(100,NULL,'KNIGHT');
INSERT INTO TBLAGENT VALUES(200,NULL,'SUPES');
INSERT INTO TBLAGENT VALUES(300,NULL,'SPIDEY');

CREATE TABLE TBLSERVICES(AGENTID NUMBER, SERVICES NUMBER);
INSERT INTO TBLSERVICES VALUES(100,44);
INSERT INTO TBLSERVICES VALUES(200,13);
INSERT INTO TBLSERVICES VALUES(300,24);
INSERT INTO TBLSERVICES VALUES(100,34);
INSERT INTO TBLSERVICES VALUES(200,13);
INSERT INTO TBLSERVICES VALUES(300,24);

SELECT TA.AGENTID, SUM(SERVICES), TA.AGENTNAME, TA.NUMBERSENT 
       FROM TBLAGENT TA, TBLSERVICES TS
       WHERE TA.AGENTID = TS.AGENTID
       GROUP BY TA.AGENTID, TA.AGENTNAME, TA.NUMBERSENT

要求是使用 tblServices 表中的 SUM(Services) 更新 tblAgent 表中的 NUMBERSENT 列。

我想出了这个更新声明。

/*Works*/
UPDATE tblagent t
   SET t.numbersent =
       (SELECT SUM(services)
          FROM tblservices x
         WHERE t.agentid = x.agentid
         GROUP BY x.agentid)

当我将此语句的语法更改为 INNER JOIN 语法时,它失败。

/*Throws an error*/
UPDATE tblagent t
   SET t.numbersent =
       (SELECT SUM(services)
          FROM tblservices x INNER JOIN tblAgent t
         ON t.agentid = x.agentid
         GROUP BY x.agentid)

这会引发错误 ORA-01427:单行子查询返回多于一行

为什么第二个语句会引发错误?

Here's a simplified version of my table.

CREATE TABLE TBLAGENT(AGENTID NUMBER, NUMBERSENT NUMBER, AGENTNAME VARCHAR2(100));
INSERT INTO TBLAGENT VALUES(100,NULL,'KNIGHT');
INSERT INTO TBLAGENT VALUES(200,NULL,'SUPES');
INSERT INTO TBLAGENT VALUES(300,NULL,'SPIDEY');

CREATE TABLE TBLSERVICES(AGENTID NUMBER, SERVICES NUMBER);
INSERT INTO TBLSERVICES VALUES(100,44);
INSERT INTO TBLSERVICES VALUES(200,13);
INSERT INTO TBLSERVICES VALUES(300,24);
INSERT INTO TBLSERVICES VALUES(100,34);
INSERT INTO TBLSERVICES VALUES(200,13);
INSERT INTO TBLSERVICES VALUES(300,24);

SELECT TA.AGENTID, SUM(SERVICES), TA.AGENTNAME, TA.NUMBERSENT 
       FROM TBLAGENT TA, TBLSERVICES TS
       WHERE TA.AGENTID = TS.AGENTID
       GROUP BY TA.AGENTID, TA.AGENTNAME, TA.NUMBERSENT

The requirement is to update the NUMBERSENT column in the tblAgent table with the SUM(Services) from tblServices table.

I came up with this update statement.

/*Works*/
UPDATE tblagent t
   SET t.numbersent =
       (SELECT SUM(services)
          FROM tblservices x
         WHERE t.agentid = x.agentid
         GROUP BY x.agentid)

When I change the syntax of this statement to INNER JOIN syntax, it fails.

/*Throws an error*/
UPDATE tblagent t
   SET t.numbersent =
       (SELECT SUM(services)
          FROM tblservices x INNER JOIN tblAgent t
         ON t.agentid = x.agentid
         GROUP BY x.agentid)

This throws up an error ORA-01427: single-row subquery returns more than one row

Why would the second statement throw an error?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

风为裳 2024-10-08 09:56:56

让我们更详细地看看这 2 个查询是如何工作的:

首先,有效的一个:

/*Works*/
UPDATE tblagent t
   SET t.numbersent =
       (SELECT SUM(services)
          FROM tblservices x
         WHERE t.agentid = x.agentid
         GROUP BY x.agentid)

显然子查询必须返回一个值以在 SET 中使用,所以让我们单独看看它:

        SELECT SUM(services)
          FROM tblservices x
         WHERE t.agentid = x.agentid
         GROUP BY x.agentid

注意这里的“t”别名将子查询与外部查询相关联 - 即,当评估子查询时,它具有一个特定值,例如

        SELECT SUM(services)
          FROM tblservices x
         WHERE 123 = x.agentid
         GROUP BY x.agentid

因此,尽管查询按 x.agentid 对结果进行分组,但实际上只有一个 x.agentid 值,即 t.agentid 的当前值(例如123)。所以这有效。

现在看看第二个查询的子查询:

       SELECT SUM(services)
         FROM tblservices x INNER JOIN tblAgent t
           ON t.agentid = x.agentid
       GROUP BY x.agentid

这次 t.agentid 不是对外部查询的引用,因此该查询与外部查询相关。它可以返回多于1行(只需运行它并查看),因此不能在外部查询的SET子句中安全使用。

Let's look at how the 2 queries work in more detail:

First, the one that works:

/*Works*/
UPDATE tblagent t
   SET t.numbersent =
       (SELECT SUM(services)
          FROM tblservices x
         WHERE t.agentid = x.agentid
         GROUP BY x.agentid)

Clearly the subquery must return a single value to use in the SET, so let's look at that on its own:

        SELECT SUM(services)
          FROM tblservices x
         WHERE t.agentid = x.agentid
         GROUP BY x.agentid

Note that the "t" alias here correlates the subquery to the outer query - i.e. it has one specific value when the subquery is evaluated e.g.

        SELECT SUM(services)
          FROM tblservices x
         WHERE 123 = x.agentid
         GROUP BY x.agentid

Therefore, although the query groups results by x.agentid, there is only in fact one x.agentid value i.e. the current value of t.agentid (e.g. 123). So this works.

Now look at the second query's subquery on its own:

       SELECT SUM(services)
         FROM tblservices x INNER JOIN tblAgent t
           ON t.agentid = x.agentid
       GROUP BY x.agentid

This time t.agentid is not a reference to the outer query, so this query is not correlated to the outer query. It can return more than 1 row (just run it and see), and thus cannot be safely used in the SET clause of the outer query.

尛丟丟 2024-10-08 09:56:56

@Tony Andrews 是对的,如果你仍然想使用 INNER JOIN 你应该这样写:(

 UPDATE tblagent t1
   SET t1.numbersent =
       (SELECT SUM(services)
          FROM tblservices x INNER JOIN tblAgent t
         ON t.agentid = x.agentid
         GROUP BY x.agentid
         having t1.agentid = x.agentid)

为了让上部和内部 DML 有一个公共列,不要返回多于一行)

但是当然我认为这只是使你的工作复杂化,仅此而已......使用第一个变体......这是更好的建议。

@Tony Andrews is right and if you still want to use INNER JOIN you should write this:

 UPDATE tblagent t1
   SET t1.numbersent =
       (SELECT SUM(services)
          FROM tblservices x INNER JOIN tblAgent t
         ON t.agentid = x.agentid
         GROUP BY x.agentid
         having t1.agentid = x.agentid)

(To have upper and inner DML one common column,for not to return more than one row)

But of course I think this is just complicating your job and nothing more..Use the first variant...This is better Advice.

溺渁∝ 2024-10-08 09:56:56

您是否尝试单独运行子查询以确保它只返回一行?

Did you try running the subquery by itself to make sure it only returns one row?

没有心的人 2024-10-08 09:56:56

您使用 INNER JOIN 重新分配 t,因此外部 t 不再链接到 UPDATE。

You reassign t with the INNER JOIN, so the outer t is not linked to the UPDATE any more.

猥琐帝 2024-10-08 09:56:56

实际上现在我想起来,第一个版本是相关子查询,第二个版本不是。没有数据可以尝试,我无法告诉你,但这可能与它有关。

Actually now that I think about it, the first version is a correlated subquery, the second one is not. Without data to try it with I couldn't tell you but that probably has something to do with it.

迷途知返 2024-10-08 09:56:56

tblAgent 中有两行具有相同的 agentid。如果没有 agentid 为 NULL 的情况,您可能不会注意到这一点。

检查:

select * from
(
    SELECT count(*) c, agentid from tblAgent group by agentid
) x
where x.c > 1

如果有任何行返回,那就是你的问题。

You have two rows in tblAgent with the same agentid. This might have escaped your notice if there are no where agentid is NULL.

To check:

select * from
(
    SELECT count(*) c, agentid from tblAgent group by agentid
) x
where x.c > 1

If any rows come back, that's your problem.

十级心震 2024-10-08 09:56:56

加入,不应该是这样吗?

(SELECT x.agentid, SUM(services)
      FROM tblservices x INNER JOIN tblAgent t
     ON t.agentid = x.agentid
     GROUP BY x.agentid)

如果您是通过agentid 加入,或者

(SELECT  SUM(services)
      FROM tblservices x INNER JOIN tblAgent t
     ON t.agentid = x.agentid
     )

不是通过agentid

Shouldn't that be

(SELECT x.agentid, SUM(services)
      FROM tblservices x INNER JOIN tblAgent t
     ON t.agentid = x.agentid
     GROUP BY x.agentid)

if you're joining by agentid, or

(SELECT  SUM(services)
      FROM tblservices x INNER JOIN tblAgent t
     ON t.agentid = x.agentid
     )

if you're not?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文