仅当每个唯一列值不存在时才为每个唯一列值添加一行

Posted

技术标签:

【中文标题】仅当每个唯一列值不存在时才为每个唯一列值添加一行【英文标题】:Add a row for each unique column value only if it doesn't already exist 【发布时间】:2020-07-19 20:05:23 【问题描述】:

我有两个表:IsCompanyValidCompanyData

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?

【讨论】:

感谢您为我指明正确的方向欧文!也感谢您的其他建议!

以上是关于仅当每个唯一列值不存在时才为每个唯一列值添加一行的主要内容,如果未能解决你的问题,请参考以下文章

大查询 - 仅在列值不存在时插入

如何使用 for 循环将列值添加到数据框字典中,以便每个数据框都有一个唯一的列?

仅当低于 100 时才增加列值

Pandas 按唯一列值拆分数据框

按其他列值获取列中每个唯一值的前 x% 行

使用 Javascript 在动态添加删除行中计算行值和列值