无法在嵌套查询的结果上添加 WHERE 约束 - postgres 中的错误 42883
Fail to add WHERE constraint on result of nested query - ERROR 42883 in postgres
这对我来说似乎是一个非常直接的嵌套查询 - 但显然我完全遗漏了一些东西。
设置:
我有两个表 ccod
和 psc
。
psc
有 col company_number
,我想在
上匹配
ccod.company_number_1
或 ccod.company_number_2
。
鉴于表格很大,我使用一些先验知识来减少要匹配的公司编号的数量:
公司编号不能为空
公司编号必须是 8 个字符长
psc.company_number
是干净的,只包含 8 个字符的长字符串。
ccod.company_number_1
或 ccod.company_number_2
包含大量垃圾。
ccod.company_number_1
或 ccod.company_number_2
都可以为空,都包含一个字符串或其中一个包含一个。
我暂时不关心重复项。
加上
- 使用
UNION ALL
创建 1 个单列作为连接 ccod
的两列的结果 - 将其别名为 stacked_company_numbers
.
所以:
SELECT *
INTO ccod_psc
FROM psc
WHERE (SELECT DISTINCT psc.company_number)
in
(SELECT DISTINCT stacked_company_numbers
FROM (SELECT company_number_1
FROM ccod
WHERE company_number_1 is not null
UNION ALL
SELECT company_number_2
FROM ccod
WHERE company_number_2 is not null) AS stacked_company_numbers
WHERE char_length(stacked_company_numbers::text) = 8);
[42883] ERROR: operator does not exist: text = record
Hint: No operator matches the given name and argument types. You might need to add explicit type casts.
Position: 86
现在这个错误的话已经很不言自明了,但我不知道如何解决它,并且尝试了很多与错误 42883 相关的其他答案,但都没有成功。
感谢您的帮助。
-- 编辑:
我还找到了一种使查询有效的方法:
SELECT *
INTO ccod_psc
FROM psc
WHERE (SELECT DISTINCT psc.company_number)
in
(SELECT company_number_1
FROM ccod
WHERE company_number_1 is not null
UNION -- this takes cares of the duplicates.
SELECT company_number_2
FROM ccod
WHERE company_number_2 is not null) AS stacked_company_numbers
WHERE char_length(stacked_company_numbers::text) = 8)
我怀疑 exists
做了你想要的:
select p.*
from psc p
where
char_length(p.company_numbers::text) = 8
and exists (
select 1
from ccod c
where p.company_number in (c.company_number_1, c.company_number_2)
)
查询从psc
中取出记录,其company_number
长度为8个字符,可以在table中的company_number_1
或company_number_2
中找到ccod
.
我认为两个 left join
效率更高:
SELECT p.*
INTO ccod_psc c
FROM psc p LEFT JOIN
ccod c1
ON p.company_number = c1.company_number_1 LEFT JOIN
ccod c2
ON p.company_number = c2.company_number_2 AND
c1.company_number_1 IS NULL
WHERE c1.company_number_1 IS NOT NULL OR
c2.company_number_2 IS NOT NULL
这种方法的优点是可以在 ccod(company_number_1)
和 ccod(company_number_2)
上使用索引。
编辑:
如果 ccod
中可以有重复项,那么 exists
可能会有更好的性能:
SELECT p.*
INTO ccod_psc c
FROM psc p
WHERE EXISTS (SELECT 1
FROM ccod c1
WHERE p.company_number = c1.company_number_1
) OR
EXISTS (SELECT 1
FROM ccod c2
WHERE p.company_number = c2.company_number_2
) ;
这对我来说似乎是一个非常直接的嵌套查询 - 但显然我完全遗漏了一些东西。
设置:
我有两个表
ccod
和psc
。psc
有 colcompany_number
,我想在 上匹配
ccod.company_number_1
或ccod.company_number_2
。
鉴于表格很大,我使用一些先验知识来减少要匹配的公司编号的数量:
公司编号不能为空
公司编号必须是 8 个字符长
psc.company_number
是干净的,只包含 8 个字符的长字符串。ccod.company_number_1
或ccod.company_number_2
包含大量垃圾。ccod.company_number_1
或ccod.company_number_2
都可以为空,都包含一个字符串或其中一个包含一个。我暂时不关心重复项。
加上
- 使用
UNION ALL
创建 1 个单列作为连接ccod
的两列的结果 - 将其别名为stacked_company_numbers
.
所以:
SELECT *
INTO ccod_psc
FROM psc
WHERE (SELECT DISTINCT psc.company_number)
in
(SELECT DISTINCT stacked_company_numbers
FROM (SELECT company_number_1
FROM ccod
WHERE company_number_1 is not null
UNION ALL
SELECT company_number_2
FROM ccod
WHERE company_number_2 is not null) AS stacked_company_numbers
WHERE char_length(stacked_company_numbers::text) = 8);
[42883] ERROR: operator does not exist: text = record
Hint: No operator matches the given name and argument types. You might need to add explicit type casts.
Position: 86
现在这个错误的话已经很不言自明了,但我不知道如何解决它,并且尝试了很多与错误 42883 相关的其他答案,但都没有成功。
感谢您的帮助。
-- 编辑:
我还找到了一种使查询有效的方法:
SELECT *
INTO ccod_psc
FROM psc
WHERE (SELECT DISTINCT psc.company_number)
in
(SELECT company_number_1
FROM ccod
WHERE company_number_1 is not null
UNION -- this takes cares of the duplicates.
SELECT company_number_2
FROM ccod
WHERE company_number_2 is not null) AS stacked_company_numbers
WHERE char_length(stacked_company_numbers::text) = 8)
我怀疑 exists
做了你想要的:
select p.*
from psc p
where
char_length(p.company_numbers::text) = 8
and exists (
select 1
from ccod c
where p.company_number in (c.company_number_1, c.company_number_2)
)
查询从psc
中取出记录,其company_number
长度为8个字符,可以在table中的company_number_1
或company_number_2
中找到ccod
.
我认为两个 left join
效率更高:
SELECT p.*
INTO ccod_psc c
FROM psc p LEFT JOIN
ccod c1
ON p.company_number = c1.company_number_1 LEFT JOIN
ccod c2
ON p.company_number = c2.company_number_2 AND
c1.company_number_1 IS NULL
WHERE c1.company_number_1 IS NOT NULL OR
c2.company_number_2 IS NOT NULL
这种方法的优点是可以在 ccod(company_number_1)
和 ccod(company_number_2)
上使用索引。
编辑:
如果 ccod
中可以有重复项,那么 exists
可能会有更好的性能:
SELECT p.*
INTO ccod_psc c
FROM psc p
WHERE EXISTS (SELECT 1
FROM ccod c1
WHERE p.company_number = c1.company_number_1
) OR
EXISTS (SELECT 1
FROM ccod c2
WHERE p.company_number = c2.company_number_2
) ;