将一个表的列中的数据与另一个表中的同一列进行比较
Posted
技术标签:
【中文标题】将一个表的列中的数据与另一个表中的同一列进行比较【英文标题】:Comparing data in a column of one table with the same column in another table 【发布时间】:2014-06-11 08:59:43 【问题描述】:我分别有两张表 temp 和 md。有一个名为 uri_stem 的字段,其中有一些我想从 temp 中省略而不是从 md 中省略的细节。如果 md 中有类似的模式,我需要进行比较,以便能够比较某些模式并将它们从 temp 中删除。
现在我正在使用此代码删除与我想省略的模式相似的数据,但我想要一些能够比较 md 表中的模式的方法,而不是我对每个模式进行硬编码。希望解释足够清楚。
FROM
spfmtr01.tbl_1c_apps_log_temp
where
uri_stem not like '%.js' and
uri_stem not like '%.css' and
uri_stem not like '%.gif'
and uri_stem not like '%.png'
and uri_stem not like '%.html'
and uri_stem not like '%.jpg'
and uri_stem not like '%.jpeg'
and uri_stem not like '%.ico'
and uri_stem not like '%.htm'
and uri_stem not like '%.pdf'
and uri_stem not like '%.Png'
and uri_stem not like '%.PNG'
【问题讨论】:
This 应该可以帮助你部分 【参考方案1】:这个例子是基于我在评论中提到的answer。
SQLFiddle
样本数据:
drop table if exists a, b;
create table a (testedstr varchar);
create table b (condstr varchar);
insert into a values
('aa.aa.jpg'),
('aa.aa.bjpg'), -- no match
('aa.aa.jxpg'), -- no match
('aa.aa.jPg'),
('aa.aa.aico'), -- no match
('aa.aa.ico'),
('bb.cc.dd.icox'), -- no match
('bb.cc.dd.cco'); -- no match
insert into b values ('jpg'), ('ico');
解释:
在表a
中有我们想要测试的字符串(存储在testedstr
列中)
在表 b
中,我们有想要用作测试表达式的字符串(存储在 condstr
列中)
SQL:
with cte as (select '\.(' || string_agg(condstr,'|') || ')$' condstr from b)
select * from a, cte where testedstr !~* condstr;
解释:
在第一行中,我们将所有想要测试的模式聚合到一个字符串中;结果,我们将得到jpg|ico
字符串(聚合为单行)。
在第二行中,我们将测试表与我们的测试表达式(来自第一行)交叉连接,并使用正则表达式来执行测试。
最后的正则表达式看起来像\.(jpg|ico)$
对于旧版本,您应该使用@Bohemian 提供的答案。对于我的示例数据,它看起来像(针对多个可能的点进行了调整)(SQLFiddle:
select
*
from
a
where
lower(reverse(split_part(reverse(testedstr),'.',1)))
not in (select lower(condstr) from b)
没有reverse
函数(SQLFiddle):
select
*,
lower(split_part(testedstr,'.',length(testedstr)- length(replace(testedstr,'.','')) + 1)) as extension
from
a
where
lower(split_part(testedstr,'.',length(testedstr)- length(replace(testedstr,'.','')) + 1)) not in (select lower(condstr) from b)
【讨论】:
@user3455309 和上面写的一样,你检查过SQLFiddle上的例子吗? 您好,感谢您的帮助,但我们使用的 Postgresql 版本非常低。 8.2 我猜所以它不支持 cte。此代码还有其他替代方法吗? @user3455309 选项 1:升级,选项 2:查看我编辑的答案。 谢谢。虽然升级听起来是一个不错的选择,但不幸的是它不在我手中。我尝试了您的查询,但它抛出错误“函数反向(字符变化)不存在”。 @user3455309 是的,我的错,古代版本没有reverse
功能。查看我更新的答案,这次我检查了 8.2 是否支持所有功能【参考方案2】:
首先让我们将许多条件重构为一个:
where lower(substring(uri_stem from '[^.]+$')) not in ('js', 'css', 'gif', 'png', 'html', 'jpg', 'jpeg', 'ico', 'htm', 'pdf')
在这种形式中,很容易看出如何选择值列表而不是编码:
where lower(substring(uri_stem from '[^.]+$')) not in (
select lower(somecolumn) from sometable)
注意使用 lower() 以避免处理大小写变体的问题。
您也可以将其编码为连接:
select t1.*
from mytable t1
left join sometable t2
on lower(somecolumn) = lower(split_part(uri_stem, '.', 2))
where t2.somecolumn is null -- filter out matches
【讨论】:
这假设字符串中只有一个点。使用select lower(reverse(split_part(reverse('aaa.bbb.cCc'),'.',1)))
之类的东西来获取字符串中最后一个点之后的部分字符串不是更好吗?
正是我想提到的。字符串有多个点。这是一个需要比较的字符串示例。 /Core/Scripts/jquery.flipCounter.1.2.js
@TomasGreif 是的,你是对的,但有一个更简单的解决方法:你可以使用正则表达式 substring(uri_stem from '[^.]+$')
提取所有尾随非点字符 - 请参阅编辑
@user3455309 我的第一个剪辑不适合多个点,但请参阅编辑以了解如何使用正则表达式 substring(uri_stem from '[^.]+$')
提取所有尾随非点字符,它适用于任意数量的点(不包括点)以上是关于将一个表的列中的数据与另一个表中的同一列进行比较的主要内容,如果未能解决你的问题,请参考以下文章