[英]How to select only *columns* with more than one distinct value?
SELECT DISTINCT …
刪除重復的行。 有沒有辦法刪除重復的列,即每個值都相同的列? 我正在查看一些行的“顯着特征”的遺留模式,所以這將非常有幫助。 如果它更容易,所有的列都是簡單的類型,如INT
、 TEXT
和TIMESTAMP
。 基本上,給定這樣的表:
CREATE TEMPORARY TABLE column_test
(
foo TEXT,
bar INT,
baz BOOLEAN,
bat TIMESTAMP WITH TIME ZONE
);
INSERT INTO column_test (
foo, bar, baz, bat
) VALUES
('lorem ipsum', 1, TRUE, '2000-01-01 UTC'),
('lorem ipsum', 2, TRUE, '2000-01-01 UTC'),
('other', 3, TRUE, '2000-01-01 UTC');
是否可以編寫一個查詢 select 只有foo
和bar
列,因為這些是唯一具有多個值的列? 像這樣的東西:
SELECT columns_with_more_than_one_value(*) FROM column_test;
foo bar
'lorem ipsum' 1
'lorem ipsum' 2
'other' 3
我想一種方法是SELECT *
,轉置結果,刪除所有值相同的任何行,然后再次轉置,但這會非常復雜,我不知道如何保留原始列名結果。
基本上你不能 select 來自表的未知列。 查詢結果在執行之前必須具有定義的結構。 您可以做的是創建一個包含預期列的(臨時)視圖。 下面的 function 完成了這項工作,廣泛使用動態 SQL。 function 的第一個參數是表名,第二個參數是要創建的臨時視圖的名稱。
create or replace function create_view_with_distinct_columns(text, text)
returns void language plpgsql as $$
declare
col text;
ct int;
list text = '';
begin
for col in
execute format('
select attname
from pg_attribute
where attrelid = %s
and attnum > 0',
$1::regclass::oid)
loop
execute format('
select count(distinct %I)
from %I',
col, $1)
into ct;
if ct > 1 then
list:= format('%s%s,', list, col);
end if;
end loop;
execute format('
create temp view %I as
select %s
from %I',
$2, left(list, -1), $1);
end $$;
利用:
select create_view_with_distinct_columns('column_test', 'column_view');
select * from column_view;
foo | bar
-------------+-----
lorem ipsum | 1
lorem ipsum | 2
other | 3
(3 rows)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.