sql >> データベース >  >> RDS >> PostgreSQL

PostgreSQLエラー:FROMのサブクエリは同じクエリレベルの他のリレーションを参照できません

    デバッグのために、テストシナリオを作成しました。
    質問のセットアップにそれを含める必要があります。

    -- drop schema x CASCADE;
    create schema x
    create table x.users(id int);
    create table x.demographics (user_id int, gender text);
    
    INSERT INTO x.users VALUES (1),(2),(3),(4),(5);
    INSERT INTO x.demographics VALUES (1, 'm'),(2, 'f'),(3, 'm'),(4, 'f'),(5, 'm');
    

    これは、いくつかの修正を行った後、現在機能しています:

    create type x.similarity as (
      distance    float,
      explanation text
    );
    
    create or replace function x.similarity_gender(my_gender text, other_gender text)
    returns x.similarity as $$
      declare
        distance  float;
        sim       x.similarity;
      begin
        if my_gender is null or other_gender is null then
          distance = 0.9;
        elsif (my_gender = other_gender) then
          distance = 0.0;
        else
          distance = 1.0;
        end if;
    
        sim.distance     = distance;
        sim.explanation  = hstore('gender', cast(sim.distance as text));
        return sim;
      end;
    $$ language plpgsql immutable;
    
    
    create or replace function x.similarity(my_user_id int)
    returns table(user_id int, distance float, explanation text) as $$
    
      with factors as (
        select u.id as user_id, d.gender
        from x.users u
        join x.demographics d on u.id = d.user_id),
    
      my_factors as (
        select f.user_id, f.gender
        from factors  f
        where f.user_id = $1),
    
      similarities as (
        select f.user_id, x.similarity_gender(m.gender, f.gender) AS sim
        from factors f, my_factors m)
    
      select s.user_id, (s.sim).distance, (s.sim).explanation
        from similarities s;
    $$ language sql stable strict;
    

    電話:

    test=# SELECT * FROM x.similarity(2);
     user_id | distance |  explanation
    ---------+----------+---------------
           1 |        1 | "gender"=>"1"
           2 |        0 | "gender"=>"0"
           3 |        1 | "gender"=>"1"
           4 |        0 | "gender"=>"0"
           5 |        1 | "gender"=>"1"
    

    主なポイント

    • 最初に関数を作成します。セットアップで実行順序を逆にします
    • 関数の類似性では、同じ名前のOUTパラメーター(user_idとの名前の競合を回避するために、列名を修飾する必要があります 、distanceexplanation
    • CTEの類似性が損なわれました。関数呼び出しsimilarity_gender(..)をSELECTリストに追加しました。 2回呼び出さないように、次のステップで分割します。
    • 括弧を使用して、複合型のフィールドにアクセスします。 こちらの細かいマニュアル を参照してください 。
    • 関数similarity()の戻りタイプにバグがありました:explanation hstoreexplanation textである必要があります 。



    1. SQL ServerFORXMLパ​​スは繰り返しノードを作成します

    2. 相関サブクエリによる効率的な結合

    3. MySQLWorkbenchインサート

    4. MySQLで結合にインデックスを強制的に使用するための構文は何ですか