postgresql函数在Where子句中使用时会导致行数不一致

发布于 2025-02-09 04:00:46 字数 2146 浏览 1 评论 0原文

我有一个函数“实验。

例如,如果我称此函数为这样:

SELECT 
 experiments.get_random_experiment_group('1a8cd547-8de6-4602-9103-3cea12f57365');

它将始终返回与该实验相关的2组ID中的1个。

但是,如果我做这样的事情...:

SELECT 
 id, 
 experiment_id,
 proportion 
FROM 
 experiments."group" 
WHERE 
 id = experiments.get_random_experiment_group('1a8cd547-8de6-4602-9103-3cea12f57365');

有时我会得到1行,2行或根本没有行。

为什么在第一种情况下它的行为是按照预期的,而在第二种情况下则不如预期的那样?关于正在发生的事情有什么建议吗?

这是功能:

CREATE OR REPLACE FUNCTION experiments.get_random_experiment_group (experiment uuid)
    RETURNS uuid
    LANGUAGE plpgsql
AS 
    $function$
DECLARE
   result uuid;
BEGIN
    WITH 
        CTE 
    AS 
    ( 
        SELECT 
            random() * (SELECT SUM(g.proportion) FROM experiments."group" g WHERE g.experiment_id = experiment) AS r
    )
    SELECT 
        id
    INTO 
        result
    FROM 
    (
        SELECT 
            id, 
            SUM(proportion) OVER (ORDER BY id) AS s,
            r
        FROM 
        (
            SELECT 
                * 
            FROM 
                experiments."group" g
            WHERE 
                g.experiment_id = experiment
        ) a 
        CROSS JOIN 
            CTE
    ) q
WHERE 
    s >= r
ORDER BY 
    id
LIMIT 
    1;
return result;
end;
$function$;

此功能的目的是为给定的实验ID随机选择组ID。选择特定组的概率由分配给该组的“比例”给出。

And here are all of the groups associated with the experiment in my example:

idexperiment_idproportion
95cc9e77-3dff-48d9-91cb-3e17c0c24d5a1a8cd547-8de6-4602-9103-3cea12f573650.5
47469555-88fd-4cec-925f-9cf15b91bca01a8cd547-8de6- 4602-9103-3CEA12F573650.5

我正在使用Postgres版本13.4

I have a function "experiments.get_random_experiment_group(experiment)" that when called in isolation behaves normally, but when called in a WHERE clause results in zero or more rows being returned.

For example, if I call this function like so:

SELECT 
 experiments.get_random_experiment_group('1a8cd547-8de6-4602-9103-3cea12f57365');

it will always return 1 of the 2 groups ids associated with that experiment.

But if I do something like this...:

SELECT 
 id, 
 experiment_id,
 proportion 
FROM 
 experiments."group" 
WHERE 
 id = experiments.get_random_experiment_group('1a8cd547-8de6-4602-9103-3cea12f57365');

I will sometimes get 1 row, 2 rows, or no rows at all.

Why is it behaving as expected in the first case, but not in the second? Any suggestions as to what's happening?

Here is the function:

CREATE OR REPLACE FUNCTION experiments.get_random_experiment_group (experiment uuid)
    RETURNS uuid
    LANGUAGE plpgsql
AS 
    $function$
DECLARE
   result uuid;
BEGIN
    WITH 
        CTE 
    AS 
    ( 
        SELECT 
            random() * (SELECT SUM(g.proportion) FROM experiments."group" g WHERE g.experiment_id = experiment) AS r
    )
    SELECT 
        id
    INTO 
        result
    FROM 
    (
        SELECT 
            id, 
            SUM(proportion) OVER (ORDER BY id) AS s,
            r
        FROM 
        (
            SELECT 
                * 
            FROM 
                experiments."group" g
            WHERE 
                g.experiment_id = experiment
        ) a 
        CROSS JOIN 
            CTE
    ) q
WHERE 
    s >= r
ORDER BY 
    id
LIMIT 
    1;
return result;
end;
$function$;

The purpose of this function is to randomly select a group id for a given experiment id. The probability of selecting a particular group is given by the “proportion” assigned to that group.

And here are all of the groups associated with the experiment in my example:

idexperiment_idproportion
95cc9e77-3dff-48d9-91cb-3e17c0c24d5a1a8cd547-8de6-4602-9103-3cea12f573650.5
47469555-88fd-4cec-925f-9cf15b91bca01a8cd547-8de6-4602-9103-3cea12f573650.5

I am using postgres version 13.4

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

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

发布评论

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

评论(1

第七度阳光i 2025-02-16 04:00:46

该函数在“组”表中的每一行都被调用,因此仅当该行的组ID发生在函数调用返回的随机生成的ID时,才返回行。

感谢评论者指出了这一点。

The function was getting called for each row in the "group" table, and thus returning rows when and only when the group id of that row happened to correspond to the randomly generated id returned by the function call.

Thanks to the commenters for pointing this out.

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