web-dev-qa-db-ja.com

Postgresの配列列の内部結合

Postgres9.4では、特定のテーブルのUNIQUE制約に関係するすべての列の名前をプルしようとしていますPostgres。

そのような列の名前はpg_constraintに含まれているようです。 ドキュメント によると、私の問題に関連する列はconkeyと呼ばれ、たまたまintsの配列です。

ポイントは、私が思いついたクエリは私に間違った結果を与えており、私はconkeyに間違った方法で参加しているためだと確信しています。クエリは次のとおりです。

SELECT
    pg_attribute.attname,
    pg_constraint.*
FROM
    pg_attribute
INNER JOIN pg_constraint 
        ON pg_attribute.attnum = ANY (pg_constraint.conkey)
WHERE pg_constraint.conrelid = (
    SELECT
        oid
    FROM
        pg_class
    WHERE
        relname LIKE 'test_table'
)
AND pg_constraint.contype = 'u'; -- to filter out non-unique constraints

以下は、簡単な再現のためのテーブルDDLです。

CREATE TABLE "test_table" (
"date" date DEFAULT now() NOT NULL,
"foo" varchar COLLATE "default" NOT NULL
CONSTRAINT "test_table_foo_key" UNIQUE ("foo")
)
WITH (OIDS=FALSE);

ALTER TABLE "test_table" OWNER TO "postgres";

今、誰かが私が間違っていることを教えてもらえますか?必要な情報をまとめて入手する簡単な方法はありますか?

私が書いているアプリはPostgresでのUPSERTの現在の欠如を回避する必要があるので、制約付きテーブルの名前を取得しようとしています。アイデアは、CTEを使用して挿入または更新を行うことですが、制約された列が事前に何であるかがわからないため、このビットのイントロスペクションを行う必要があります。

6
s.m.

2つのテーブル間の接続が半分失われます。 ...relid列も一致する必要があります:

SELECT attname, c.* 
  FROM pg_attribute a 
  JOIN pg_constraint c 
    ON attrelid = conrelid -- this was missing
   AND attnum = ANY (conkey) 
 WHERE attrelid = 'test_table'::regclass;
6
dezso