ホームページ > データベース > mysql チュートリアル > PostgreSQL クエリで使用すると、セットを返す関数の列が連結されるのはなぜですか?これを解決するにはどうすればよいですか?

PostgreSQL クエリで使用すると、セットを返す関数の列が連結されるのはなぜですか?これを解決するにはどうすればよいですか?

Barbara Streisand
リリース: 2024-12-28 17:07:10
オリジナル
416 人が閲覧しました

Why are my set-returning function's columns concatenated when used in a PostgreSQL query, and how can I resolve this?

関数から返されたレコード内の連結列

この問題は、別のクエリ内でセットを返す関数を利用してクエリを実行しようとすると発生し、その結果、すべての関数が返されます。列を 1 つの列に連結します。

関数宣言

次の Postgres 関数 account_servicetier_for_day は、アカウント ID と日を受け取り、履歴データを返します:

CREATE OR REPLACE FUNCTION account_servicetier_for_day(_accountid integer, _day timestamp without time zone) RETURNS setof account_dsl_history_info AS
$BODY$
DECLARE _accountingrow record;
BEGIN
  Return Query
  Select * From account_dsl_history_info
  Where accountid = _accountid And timestamp <= _day + interval '1 day - 1 millisecond'
  Order By timestamp Desc 
  Limit 1;
END;
$BODY$ LANGUAGE plpgsql;
ログイン後にコピー

問題: 連結列

関数が直接実行すると、期待される結果が個別の列で返されます。ただし、クエリ内で使用すると、列は 1 つに連結されます。

Select
    '2014-08-12' As day, 0 As inbytes, 0 As outbytes, acct.username, acct.accountid, acct.userid,
    account_servicetier_for_day(acct.accountid, '2014-08-12')
From account_tab acct
Where acct.isdsl = 1
    And acct.dslservicetypeid Is Not Null
    And acct.accountid Not In (Select accountid From dailyaccounting_tab Where Day = '2014-08-12')
Order By acct.username
ログイン後にコピー

解決策: SQL 分解

関数から返されたレコードを個々の列に分解するには、SQL 構文を使用します。

SELECT * FROM account_servicetier_for_day(20424, '2014-08-12');
ログイン後にコピー

Postgres 9.3 または新しい

Postgres 9.3 以降の場合、クエリは JOIN LATERAL を使用して書き換えることができます:

SELECT '2014-08-12' AS day, 0 AS inbytes, 0 AS outbytes
     , a.username, a.accountid, a.userid
     , f.*   -- but avoid duplicate column names!
FROM   account_tab a
     , account_servicetier_for_day(a.accountid, '2014-08-12') f  -- <-- HERE
WHERE  a.isdsl = 1
AND    a.dslservicetypeid IS NOT NULL
AND    NOT EXISTS (
   SELECT FROM dailyaccounting_tab
   WHERE  day = '2014-08-12'
   AND    accountid = a.accountid
   )
ORDER  BY a.username;
ログイン後にコピー

Postgres 9.2 以降

Postgres 9.2 以降の場合は、サブクエリを使用しますセットを返す関数を呼び出し、外側のレコードを分解します。クエリ:

SELECT '2014-08-12' AS day, 0 AS inbytes, 0 AS outbytes
     , a.username, a.accountid, a.userid
     , (a.rec).*   -- but be wary of duplicate column names!
FROM  (
   SELECT *, account_servicetier_for_day(a.accountid, '2014-08-12') AS rec
   FROM   account_tab a
   WHERE  a.isdsl = 1
   AND    a.dslservicetypeid Is Not Null
   AND    NOT EXISTS (
       SELECT FROM dailyaccounting_tab
       WHERE  day = '2014-08-12'
       AND    accountid = a.accountid
      )
   ) a
ORDER  BY a.username;
ログイン後にコピー

以上がPostgreSQL クエリで使用すると、セットを返す関数の列が連結されるのはなぜですか?これを解決するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート