【问题标题】:The query returns values before inserting data查询在插入数据之前返回值
【发布时间】:2019-10-04 07:52:03
【问题描述】:

我有一个评分表。

CREATE TABLE merchants_rating(
    id          SERIAL PRIMARY KEY,
    user_id     INTEGER NOT NULL REFERENCES users ON DELETE CASCADE,
    merchant_id INTEGER NOT NULL REFERENCES users ON DELETE CASCADE,
    rating      INTEGER NOT NULL
);

我想往里面插入数据,得到卖家评分和评分用户数之和。

我提出了一个请求。

WITH INSERT_ROW AS (
  INSERT INTO MERCHANTS_RATING (USER_ID, MERCHANT_ID, RATING) 
  VALUES(147, 92, 2)
)
SELECT SUM(R.RATING) AS SUMMA_RATING, COUNT(R.USER_ID) AS USER_COUNT 
FROM MERCHANTS_RATING AS R 
WHERE R.MERCHANT_ID = 92

数据添加成功,但是输出有问题。当表为空并且我第一次向其中添加数据时,我会得到这样的值。

 SUMMA_RATING | USER_COUNT | 
----------------------------
     NULL     |     0      |

虽然我希望收到。

 SUMMA_RATING | USER_COUNT | 
----------------------------
      2      |      1      |

由于一位用户对卖家进行了评价。

我做错了什么?

【问题讨论】:

    标签: sql postgresql sql-insert common-table-expression


    【解决方案1】:

    Quote from the manual

    WITH 中的子语句彼此同时执行,并与主查询同时执行。因此,当在 WITH 中使用数据修改语句时,指定更新实际发生的顺序是不可预测的。所有语句都使用相同的快照执行(参见第 13 章),因此它们无法“看到”彼此对目标表的影响

    (强调我的)

    幸运的是,手册还解释了如何解决这个问题:

    这个 [...] 意味着 RETURNING 数据是在不同 WITH 子语句和主查询之间传达更改的唯一方式

    您需要在现有行和插入的行之间使用 UNION:

    WITH insert_row AS (
      INSERT INTO merchants_rating (user_id, merchant_id, rating) 
      VALUES (147, 92, 2)
      returning * --<< return the inserted row to the outer query
    )
    SELECT sum(r.rating) AS summa_rating, count(r.user_id) AS user_count 
    FROM (
      SELECT rating, user_id
      FROM merchants_rating
      WHERE merchant_id = (SELECT merchant_id FROM insert_row)
      UNION ALL
      SELECT rating, user_id
      FROM insert_row
    ) r;
    

    如果您打算在第一步中插入多行,则需要将r.merchant_id =更改为r.merchant_id IN

    在线示例:https://rextester.com/BSCI15298

    【讨论】:

    • 一个简单的插入和选择总和就可以不用这些太多的代码行
    • @ϻᴇᴛᴀʟ 绝对正确,我只是想解决最初的问题
    • r.merchant_id=92 将使 cte 在此答案中无用。
    • @ϻᴇᴛᴀʟ:我的回答中没有r.merchant_id=92
    • 我收到一个错误ERROR: subquery in FROM must have an alias LINE 7: FROM(。我该怎么办?
    【解决方案2】:

    我认为这就是你想要做的。

    1. insert_row cte 向merchants_rating 插入一些值。
    2. 从表merchants_rating中选择总和和计数
    insert into merchants_rating (user_id, merchant_id, rating) 
    with insert_row as ( 
      select 147, 92, 2 
    ) select * from insert_row;
    
    select sum(rating) AS summa_rating, count(user_id) AS user_count 
    from merchants_rating where merchant_id = 92;
    

    SQLFIDDLE

    【讨论】:

    • 公用表表达式 (WITH) 在此示例中毫无用处
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 2018-05-07
    • 1970-01-01
    • 2022-01-26
    • 1970-01-01
    • 2021-11-30
    • 1970-01-01
    相关资源
    最近更新 更多