0
我有一个包含许多(+1000)列和行(〜1M)的表。列的值为1,或者为NULL。Postgresql为一行选择具有特定值的所有列和列名称
我希望能够选择,对于一个特定行(用户)检索具有的1
由于有上表中的许多列值的列名,指定列将产生一个非常长查询。
我有一个包含许多(+1000)列和行(〜1M)的表。列的值为1,或者为NULL。Postgresql为一行选择具有特定值的所有列和列名称
我希望能够选择,对于一个特定行(用户)检索具有的1
由于有上表中的许多列值的列名,指定列将产生一个非常长查询。
您正在做的事情SQL在动态访问列或将一行视为集合时很糟糕。如果这更容易,它会很好,但它不适用于SQL的键入本质和关系的概念。以目前的形式处理您的数据集将会令人沮丧;考虑存储一个数组,json
或hstore
的值。
实际上,对于这个特定的数据模型,你可能可以使用一个位域。见bit(n)
and bit varying(n)
。
尽管仍然可以使用当前的PostgreSQL扩展模块进行工作查询。
鉴于样品:
CREATE TABLE blah (id serial primary key, a integer, b integer, c integer);
INSERT INTO blah(a,b,c) VALUES (NULL, NULL, 1), (1, NULL, 1), (NULL, NULL, NULL), (1, 1, 1);
我UNPIVOT每一行到使用hstore
(或在新的PostgreSQL版本中,JSON功能)键/值集合。 SQL自身没有办法动态访问列,所以我们必须使用扩展。所以:
SELECT id, hs FROM blah, LATERAL hstore(blah) hs;
然后提取hstore
s到集:
SELECT id, k, v FROM blah, LATERAL each(hstore(blah)) kv(k,v);
...此时您可以筛选符合标准值。请注意,所有列已转换为text
,所以你可能想将它转换回:
SELECT id, k FROM blah, LATERAL each(hstore(blah)) kv(k,v) WHERE v::integer = 1;
您还需要从配套排除id
,所以:
regress=> SELECT id, k FROM blah, LATERAL each(hstore(blah)) kv(k,v) WHERE v::integer = 1 AND
k <> 'id';
id | k
----+---
1 | c
2 | a
2 | c
4 | a
4 | b
4 | c
(6 rows)
你可以行转换为'hstore'对象,然后将其转换为单独的键和值数组,并只返回值为1的键。 –
为什么这很奇怪?转换为稀疏矩阵时,我的表格非常宽以节省空间。 –
@ManuelG这个目标很有意义,但是SQL在动态列访问方面非常糟糕。所以你节省了空间,并且交换了一个很难解决的问题。要处理这些行,你基本上必须将它们转化为键/值形式。 –