【发布时间】:2020-05-26 06:25:09
【问题描述】:
我使用的是 Postgres 12.2。
我尝试填写一种事件表,其中有一列需要获取某物的 id。
在我创建的示例中,事件存储在 purchases 表中,而 id 需要是公司的 id,取自 companies 表。由于没有固定的公司集,因此公司表需要“随我增长”;)。
所以设置是:
CREATE TABLE
companies
(
company_id SERIAL NOT NULL,
NAME CHARACTER VARYING(256) NOT NULL,
PRIMARY KEY (company_id),
CONSTRAINT companies_unique_name UNIQUE (NAME)
)
;
CREATE TABLE
purchases
(
purchase_id SERIAL NOT NULL,
purchase_date DATE DEFAULT CURRENT_DATE NOT NULL,
amount INTEGER NOT NULL,
company_id INTEGER NOT NULL,
PRIMARY KEY (purchase_id)
)
;
因此,当我现在想要插入事件“从 'company1' 购买了 5 件商品”时,我需要通过在 companies 表中查找“company1”的 id 或通过为companies 中的“company1”。
我可以这样做:
WITH EXISTING_COMPANY AS (
SELECT company_id FROM companies WHERE name = 'company1'
)
, NEW_COMPANY AS (
INSERT INTO companies (name) VALUES ('company1')
ON CONFLICT(name) DO NOTHING
RETURNING company_id
)
, GET_COMPANY_ID AS (
SELECT COALESCE(
(SELECT company_id FROM EXISTING_COMPANY),
(SELECT company_id FROM NEW_COMPANY)
) AS company_id
)
INSERT INTO purchases(amount, company_id)
VALUES (5, (select company_id from GET_COMPANY_ID))
;
CTE EXISTING_COMPANY 将为我提供现有“company1”或 null 的 ID。
CTE NEW_COMPANY 会给我一个新创建的公司“company1”或null的ID
CTE GET_COMPANY_ID 最终将通过使用 coalesce 尝试获取现有 id,如果失败,则获取新 id。
虽然这可行,但它的缺点是我需要两次提供公司名称,并且我需要为每家公司提供新的 CTE,因为我不知道如何将公司名称传递给我的 CTE。
- 有没有办法将公司名称传递给我的 CTE?
- 还有其他方法可以实现我的目标吗?
【问题讨论】:
标签: postgresql common-table-expression