1
問題
我有一個PostgreSQL 9.6數據庫,根據不同類型的值的EAV模型設計了一個表格。的示例摘錄看起來像這樣:PostgreSQL的交叉與動態列名和多輸入列
name |arrivalTime | boolValue | intValue | floatValue | stringValue
------+------------+-----------+----------+------------+------------
a1 | 10:00:00 | true | | |
c3 | 10:00:00 | | 12 | |
d4 | 10:00:00 | | | | hello
e5 | 15:00:00 | | | 45.67 |
c3 | 15:00:00 | | 45 | |
b2 | 20:00:00 | | | 4.567 |
a1 | 20:00:00 | false | | |
d4 | 22:00:00 | | | | bye
b2 | 22:00:00 | | | 12.34 |
空單元表示在數據庫中null
值。
現在我想要得到一個數據透視表,新列是arrivalTime
,內容是name
。對於示例從上面應該是這樣的:
arrivalTime | a1 | b2 | c3 | d4 | e5
------------+-------+-------+-------+-------+-------
10:00:00 | true | | 12 | hello |
15:00:00 | | | 45 | | 45.67
20:00:00 | false | 4.567 | | |
22:00:00 | | 12.34 | | bye |
作爲輸入來查詢用於檢索這個結果我得到一個圖案匹配name
S和開始和結束時間指定的arrivalTime
的範圍內。原始表的
屬性:
- 在名稱列中的條目是揮發性的,即新的名字進來 老名字經常消失。
name
和arrivalTime
的每種組合都是獨特的。- 每個
name
和arrivalTime
組合在其中一個值列中只有一個條目。
想法
我已經給了它一些注意事項:
- 我想通了這麼多,該
crosstab
功能可用於 - 由於列是動態的,將需要兩個查詢如Dynamically generate columns in PostgreSQL或Execute a dynamic crosstab query中所述。
- 使用
format()
函數生成第一個查詢可能是一個好主意。
示例表
這裏是SQL代碼來創建實例表:
CREATE TABLE IF NOT EXISTS playTable (
name TEXT NOT NULL,
arrivalTime TIME NOT NULL,
floatValue REAL NULL,
intValue INT NULL,
boolValue BOOLEAN NULL,
stringValue TEXT NULL,
PRIMARY KEY (name, arrivalTime),
CONSTRAINT single_value CHECK(
(boolValue IS NOT NULL)::INT +
(intValue IS NOT NULL)::INT +
(floatValue IS NOT NULL)::INT +
(stringValue IS NOT NULL)::INT = 1
)
);
並插入的值:
INSERT INTO playTable (name, arrivalTime, boolValue) VALUES ('a1', '10:00:00', true);
INSERT INTO playTable (name, arrivalTime, intValue) VALUES ('c3', '10:00:00', 12);
INSERT INTO playTable (name, arrivalTime, stringValue) VALUES ('d4', '10:00:00', 'hello');
INSERT INTO playTable (name, arrivalTime, floatValue) VALUES ('e5', '15:00:00', 45.67);
INSERT INTO playTable (name, arrivalTime, intValue) VALUES ('c3', '15:00:00', 45);
INSERT INTO playTable (name, arrivalTime, floatValue) VALUES ('b2', '20:00:00', 4.567);
INSERT INTO playTable (name, arrivalTime, boolValue) VALUES ('a1', '20:00:00', false);
INSERT INTO playTable (name, arrivalTime, stringValue) VALUES ('d4', '22:00:00', 'bye');
INSERT INTO playTable (name, arrivalTime, floatValue) VALUES ('b2', '22:00:00', 12.34);
透視表,非動態
klin provid我猜:
SELECT *
FROM crosstab(
$ct$
SELECT
arrivalTime, name, concat(boolValue, intValue, floatValue, stringValue)
FROM playTable
ORDER BY 1, 2
$ct$,
$ct$
SELECT DISTINCT name
FROM playTable
ORDER BY 1
$ct$)
AS ct("arrivalTime" time, "a1" BOOLEAN, "b2" REAL, "c3" INT, "d4" TEXT, "e5" REAL);
這個解決方案缺少的是動態方面。作爲輸入,提供name
的LIKE
模式,並且範圍(即,最小值和最大值)爲arrivalTime
。這使得as ct(...)
的論點變得動態。
我的解決方案發揮各地和擴展我的問題有點。我將'coalesce'改爲'concat'。 能正常工作的重要障礙採取,但我不是在終點尚未: 仍下落不明是把在模式指定'name'和'arrivalTime'範圍的能力。這使「ct(...)」動態的論點成爲可能。 – user711270
user711270您需要任何編程languge的,將生成SQL查詢你的,採取的輸入模式照顧。如果你在SQL中只使用plpgsql來創建這樣的動態查詢。 –