处理设计不良的变量列" PostgreSQL中的表

时间:2016-10-10 09:03:29

标签: sql postgresql

我正在处理一个设计不佳的表,有点像这样

create table (
   entity_key  integer,
   tag1        varchar(10),
   tag2        varchar(10),
   tag3        varchar(10),
   ...
   tag25       varchar(10)
);

实体可以具有由非空列数指示的0个或更多标记。标签都是相同的类型,应该有一个单独的标签"我们可以加入主要实体的表。

但是,我坚持使用这张(非常大)的桌子。

我想运行一个查询,该查询为我提供了不同的标记和每个标记的计数。

如果我们有标准的"标签"我们可以简单地写表

select tag, count(tag) from tags group by tag;

但是,鉴于目前的表结构,我还没有为这个查询提出一个好的方法。

2 个答案:

答案 0 :(得分:5)

您可以使用数组和不需要的数据:

select x.tag, count(*)
from tags
    cross join lateral unnest(array[tag1, tag2, tag3, tag4, tag5, tag6, tag7, ...]) as x(tag)
where x.tag is not null --<< git rid of any empty tags
group by x.tag;

这将按标签列的内容进行分组,这与Prdp的答案不同,后者按列列表中的“ position ”进行分组。

对于此示例数据:

insert into tags (entity_key, tag1, tag2, tag3, tag4, tag5)
values
(1, 'sql', 'dbms', null, null, null),
(2, 'sql', 'dbms', null, null, 'dml'),
(3, 'sql', null, null, 'ddl', null);

这将返回:

tag  | count
-----+------
dml  |     1
ddl  |     1
sql  |     3
dbms |     2

答案 1 :(得分:3)

您可以取消数据并执行count

select tag,count(data)
from
(
select tag1 as data,'tag1' as tag
from yourtable
Union All
select tag2,'tag2' as tag
from yourtable
Union All
..
select tag25,'tag25' as tag
from yourtable
) A
Group by tag

如果postgresql支持Unpivot运算符,那么您可以使用