[英]SUM & GROUP BY on an array of composite type
我有一個復合類型數組(text, decimal, timestamp)
作為數據類型的列。 我想創建一個查詢來匯總復合類型的雙列的總和。 此外,我想在日期時間的日期(日 - 月 - 年)執行一組。
誰能告訴我一個解釋如何做到這一點的例子?
表和類型的定義:
create type stage as (
Stage_Name text,
Stage_Distance decimal,
Stage_Start_Time timestamp
);
CREATE TABLE "Event" (
"Id" serial NOT NULL,
"Location" text,
"Date_Range" daterange,
"Surface" text,
"Stage_Information" stage[],
CONSTRAINT "PK_Event" PRIMARY KEY ("Id")
);
示例數據
{"(Newtownards,1.5,\"2015-04-03 18:28:00\")"
,"(\"Bulls Brook\",13.4,\"2015-04-04 09:04:00\")"}
預期成績:
總和(1.5 + 13.4)= 14.9
集團2015-04-03,2015-04-04
假設當前Postgres版本9.4缺乏信息。
首先,考慮數據庫規范化 。 另外一個表而不是"Stage_Information"
列通常是優秀的解決方案:
CREATE TABLE stage (
stage_id serial PRIMARY KEY
, event_id int NOT NULL REFERENCES event
, name text -- possibly NOT NULL
, distance numeric -- possibly NOT NULL
, starttime timestamp -- possibly NOT NULL
);
它也不占用更多的磁盤空間,陣列開銷類似於表開銷。 只有附加索引需要更多空間。 但是基表上的許多查詢會更快,更新會更便宜,而且一切都會更簡潔。
不要將引用和不引用的大寫字母與您的標識符混合使用。 這非常容易出錯。 如果可以,請專門使用不帶引號,合法的小寫名稱。
該查詢將是:
SELECT e.id, s.starttime::date AS day
, sum(s.distance) AS sum_distance
FROM "Event" e
LEFT JOIN stage s ON s.event_id = e.id
WHERE e.id = 1
GROUP BY 1, 2;
在堅持使用當前設計的同時,您需要使用unnest()
數組將聚合函數應用於其元素。 那么你需要分解復合值。 使用LATERAL
加入:
SELECT e.id, (s.st).stage_start_time::date AS day
, sum((s.st).stage_distance) AS sum_distance
FROM "Event" e
LEFT JOIN LATERAL unnest(e."Stage_Information") s(st) ON true
WHERE e.id = 1
GROUP BY 1, 2;
請注意(s.st)
周圍的括號(s.st)
列的列別名)。 您需要這些元素來訪問復合類型的元素(行類型) 。
為什么LEFT JOIN LATERAL ... ON true
嗎?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.