在Postgresql中与返回一起使用时,WITH returned table的行为是否会意外?

在Postgresql中与返回一起使用时,WITH returned table的行为是否会意外?,sql,database,postgresql,Sql,Database,Postgresql,我被难住了。为什么这个工作很好 WITH sst AS (SELECT * FROM subtopics_results WHERE student_id = 2) SELECT * FROM subtopics_results AS str WHERE (subtopic_id,student_id) IN (SELECT subtopic_id,student_id FROM sst); 但是下面的函数没有-它返回一个空表。我可以查询返回的表sst很好(例如SELECT*fromst),

我被难住了。为什么这个工作很好

WITH sst AS (SELECT * FROM subtopics_results WHERE student_id = 2)
SELECT * FROM subtopics_results AS str 
WHERE (subtopic_id,student_id) IN (SELECT subtopic_id,student_id FROM sst);
但是下面的函数没有-它返回一个空表。我可以查询返回的表
sst
很好(例如
SELECT*fromst
),但是当我尝试使用

WITH sst AS (
    -- inside block is working fine
    INSERT INTO subtopics_results (paper_id, student_id, subtopic_id, marks_scored) 
        (
            WITH subtopics AS (
            SELECT qbr.question_id, q.subtopic_id, qbr.student_id, q.paper_id, qbr.marks_scored
            FROM question AS q
            JOIN question_breakdown_result AS qbr
            ON qbr.question_id = q.question_id
            WHERE paper_id = 1 AND qbr.student_id = 2
            )
            SELECT paper_id, student_id, subtopic_id, SUM(marks_scored)
            FROM subtopics GROUP BY subtopic_id, student_id, paper_id
            HAVING SUM(marks_scored) > 2
        ) 
    RETURNING subtopic_id, student_id
) 
-- this returns an empty table, even though identical to the above.
SELECT * FROM subtopics_results AS str 
WHERE (subtopic_id,student_id) IN (SELECT subtopic_id,student_id FROM sst);
插入后,我试图选择表中的所有对
子主题\u结果
子主题id
学生id
),但没有返回任何结果,即使我确实希望得到结果

我试过内部连接,没有用


这与
返回的
语句有关吗?

该行为记录在:

(……)

WITH
中的子语句与每个子语句同时执行 与主查询的其他和。因此,在使用数据修改时
中带有
的语句,指定更新的顺序 事实上,事情的发生是不可预测的。所有语句都使用 相同的快照(请参见),因此 无法“查看”彼此对目标表的影响。(……)

(……)

可能使用
UNION ALL
来合并
RETURNING
返回的行和发生
INSERT
之前已在表中的行可以在此处执行您想要的操作

WITH
sst AS
(
INSERT INTO subtopics_results
            (...)
       RETURNING *
)
SELECT sst.*
       FROM sst
UNION ALL
SELECT str.*
       FROM subtopics_results AS str 
       WHERE (str.subtopic_id,
              str.student_id) IN (SELECT sst.subtopic_id,
                                         sst.student_id
                                         FROM sst);
或者,如果您只想返回插入的行(我不完全清楚),只需使用:

INSERT INTO subtopics_results
            (...)
       RETURNING *;

很好!谢谢@stickybit。我有一种感觉,这与执行命令有关。。为了澄清-在
union all
之前的
select
返回插入的行,在它返回已经存在的行之后的
select
,对吗?但是第二个
select
语句(在
union all
之后)不会也同时执行吗,因为它也依赖于
sst
表?为什么这一行可以正常工作?@lionbigcat:是的,第一行获取插入的行,第二行获取在收到语句之前已经在表中的行。所以它也看不到任何修改,但这并不重要,因为它在修改发生之前就得到了状态。