web-dev-qa-db-ja.com

複数行のDISTINCT制約を使用してSELECTからSQLテーブルを作成する方法

複数行のDISTINCTに基づいてSELECTステートメントからテーブルを作成したいのですが、PostgreSQLでは許可されていません。

以前に別のテーブルから要素を選択したテーブルを作成する必要があり、それらはすべて一意です。

これが私の試みです:

CREATE TABLE new_name AS (

   SELECT DISTINCT(table.field1, table.field2), table.field1, table.field2, 
   FROM ...
   WHERE ...

);

このステートメントを実行すると、PostgreSQLは次のように言います。

エラー:列「行」に疑似タイプのレコードがあります

どうすればこの問題を解決できますか?

1
DavideChicco.it

distinct[〜#〜] not [〜#〜]関数です。結果のall列に対して常に動作します。

select distinct (foo), barselect distinct foo, barの違いは、select (foo), barselect foo, barの違いと同じです。括弧は単なる「ノイズ」です。

select (foo,bar)を記述すると、実際にはPostgresで匿名のレコードタイプが作成され、2つの属性を持つ1つの列が作成されます。これは、実際には望んでいないことです。


Postgresを使用しているので、(独自の)演算子 DISTINCT ON を使用できます。これは、標準のDISTINCTとは対照的に-実行します列のサブセット。

(field1, field2)の組み合わせが同じである行が複数ある場合に、どの行を取得するかを定義するために、その場合にORDER BYを指定するします

CREATE TABLE new_name 
AS 
SELECT DISTINCT ON (table.field1, table.field2), 
       table.field1, 
       table.field2, 
       .....
FROM ...
WHERE ...
ORDER BY ..

ANSI SQLを使用したい場合は、このためのウィンドウ関数が必要です。

create table new_name
as
select column1, column2, column3, column4, column5, column6
from (
   select column1, column2, column3, column4, column5, column6, 
          row_number() over (partition by column1, column2 order by ...) as rn 
   from the_table
   where ...
) t
where rn = 1;

大きなテーブルの場合、DISTINCT ONはウィンドウ関数を使用したソリューションよりもおそらく高速です。