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在動態列訪問方面非常糟糕。所以你節省了空間,並且交換了一個很難解決的問題。要處理這些行,你基本上必須將它們轉化爲鍵/值形式。 –