仅当每个唯一列值不存在时才为每个唯一列值添加一行
Posted
技术标签:
【中文标题】仅当每个唯一列值不存在时才为每个唯一列值添加一行【英文标题】:Add a row for each unique column value only if it doesn't already exist 【发布时间】:2020-07-19 20:05:23 【问题描述】:我有两个表:IsCompanyValid
和 CompanyData
。
IsCompanyValid
:
Company IsValid
A TRUE
B TRUE
C TRUE
D FALSE
CompanyData
:
Company Data
A Data1
A Data1
A Data1
B Data1
B Data1
C Data1
D Data1
我想将名为“testData”的数据插入CompanyData
,用于每个有效的唯一公司。所以我希望CompanyData
看起来像这样:
CompanyData
:
Company Data
A Data1
A Data1
A Data1
B Data1
B Data1
C Data1
D Data1
A testData
B testData
C testData
这是我写的查询:
INSERT into CompanyData (Company, Data)
SELECT
distinct Company,
'testData'
FROM CompanyData
-- Make sure the data we are inserting is for valid companies only
WHERE Company in
(
select Company from IsCompanyValid
where IsValid = true
)
AND 'testData' not in
(
select Data from CompanyData
);
现在这工作正常。但是如果CompanyData
表被稍加修改,使得'testData' 已经存在,这个查询将不再起作用。例如:
CompanyData
:
Company Data
A Data1
A Data1
A Data1
B Data1
B Data1
C Data1
D Data1
A testData
此查询将不再插入 B 和 C。我不确定如何修改查询以插入 B 和 C。 真实数据要大得多,所以我需要将我的解决方案泛化。
【问题讨论】:
【参考方案1】:这会像请求的那样插入行:
INSERT INTO CompanyData(Company, Data)
SELECT i.Company, 'testData'::text
FROM IsCompanyValid i
WHERE i.IsValid
AND NOT EXISTS (
SELECT FROM CompanyData d
WHERE d.Company = i.Company
AND d.Data = 'testData'
);
如果已存在带有Data = 'testData'
的行,则会跳过公司。
还应该是快速和 NULL 安全的(相对于 NOT IN
),索引在 CompanyData(Company, Data)
。
或者使用更专业的部分索引甚至更快:
CREATE INDEX foo ON CompanyData(Company)
WHERE Data = 'testData';
但特殊索引只有在您继续需要时才值得。
见:
Select rows which are not present in other table另外:考虑 Postgres 中合法的、小写的、不带引号的标识符。见:
Are PostgreSQL column names case-sensitive?【讨论】:
感谢您为我指明正确的方向欧文!也感谢您的其他建议!以上是关于仅当每个唯一列值不存在时才为每个唯一列值添加一行的主要内容,如果未能解决你的问题,请参考以下文章