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

a0x5cqrl  于 2021-07-24  发布在  Java
关注(0)|答案(1)|浏览(382)

我有两张table: 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。
实际数据要大得多,所以我需要将我的解决方案推广。
jqjz2hbq

jqjz2hbq1#

按要求插入行:

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' 已经存在。
也应该是快速和空安全的(与 NOT IN )带索引的 CompanyData(Company, Data) .
或者更专业的部分索引更快:

CREATE INDEX foo ON CompanyData(Company)
WHERE  Data = 'testData';

但只有在你一直需要的情况下,特别指数才有回报。
请参见:
选择其他表中不存在的行
旁白:在postgres中考虑合法的,小写的,无引号的标识符。请参见:
postgresql列名是否区分大小写?

相关问题