首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Sybase -在SQL中创建一个测试,将两列与具有相同子字符串但位置不同的字符串进行比较。

Sybase -在SQL中创建一个测试,将两列与具有相同子字符串但位置不同的字符串进行比较。
EN

Stack Overflow用户
提问于 2017-06-16 16:43:22
回答 4查看 1.7K关注 0票数 0

标题可能有点难以理解,因为我不善于总结事物,但我试图做的实际上是非常简单(在任何其他语言)。

我想在Sybase表中测试一些数据,特别是两列。这两列都有冒号分隔的字符串,不幸的是,每个子字符串的位置在两列之间并不相同。就像这样:

column_1

减1:减3:减5 减2:减4:减6

column_2

减3:减1:减5 减6:减2:减4

我想做的是,如果column1的子字符串不等于column2的子字符串,则提供简单的pass/fail状态。我不关心子串的顺序,也不能在它们到达桌子之前改变它们的顺序。我只想说:

如果column1具有与column2相同的内容(无论顺序如何),并且如果column1或column2包含的信息不存在于另一个信息中,则测试将失败。

我可以在类似Python的东西中蒙住眼睛,但我对SQL不太精通。下面是我查询这张桌子的大致方式:

代码语言:javascript
复制
select columna, columnb, columnc, columnd, column_1, column_2, CASE <do tests here> END as test_results from table

有什么想法吗?我想保持一个尽可能简单的理想状态!

现在我知道每个子字符串都会有10个字符长,并且始终是冒号分隔的。然而,子串的数目可以从1到20不等(大多数是2或3)。

这是Sybase ASE,使用RapidSQL 8.6.1,我安装的ADE驱动程序的版本是15.07.00.1260,尽管我对我们的DB设置了解的并不多。

EN

回答 4

Stack Overflow用户

发布于 2017-06-16 16:57:10

我在这里并不完全关注这个问题,特别是如果我们知道字符串的实际长度,如果我们知道了,那就太好了,如果我们不这样做的话,下面的问题就变得更加困难了。现在,我假设10。而且,我不确定我是否跟随您的列示例,数据中是否有回车返回?还是那只是另一排?总之,一些代码可以让你开始:

代码语言:javascript
复制
if object_id('tempdb.dbo.#test') is not null drop table #test
create table #test
(
    column1 varchar(50),
    column2 varchar(50)
)

insert into #test
select 
    'substring1:substing2:substring3',
    'substring3:substring1:substring2'

select
    case 
        when substring(column1,1,charindex(':', column1)-1) = 
                substring(column2,charindex(':', column2)+1, 10)
            then 'pass' 
            else 'fail' 
            end as Substring1Test,

    case 
        when reverse(substring(reverse(column1),1,charindex(':', reverse(column1))-1)  ) =
                substring(column2,1,charindex(':', column2)-1) 
            then 'pass' 
            else 'fail' 
            end as Substring3Test

from #test
票数 0
EN

Stack Overflow用户

发布于 2017-06-16 19:41:56

Sybase ASE没有任何可以执行所需比较的内置函数。

Sybase ASE 15.0.2+的一个可用选项是创建用户定义函数(UDF)的能力。

处理所需比较的UDF示例:

代码语言:javascript
复制
use sybsystemprocs
go

if object_id('dbo.sp_f_compare') is not NULL
    drop function dbo.sp_f_compare
go

create function dbo.sp_f_compare
(@string1   varchar(300) = NULL
,@string2   varchar(300) = NULL
)
returns varchar(20)
as

declare @source varchar(300),
        @target varchar(300),
        @string varchar(20),
        @pos    smallint,
        @loop   tinyint,
        @result varchar(20)

select  @result = 'pass',
        @loop   = 1,
        @source = @string1,
        @target = ':' + @string2 + ':'

while @loop <= 2
begin
    while @source is not NULL
    begin
        select @pos = charindex(':',@source)

        if @pos = 0 select @pos = 300

        select  @string = ':' + substring(@source,     1,@pos-1) + ':',
                @source =       substring(@source,@pos+1,300   )

        if charindex(@string,@target) = 0
        begin
            select  @result = 'fail'
            break
        end
    end

    if @result = 'fail'
        break

    select  @source = @string2,
            @target = ':' + @string1 + ':',
            @loop   = @loop + 1
end

return @result
go

grant all on dbo.sp_f_compare to public
go

备注:

  • 函数名以'sp_‘开头,并安装在sybsytemprocs数据库中;这允许从数据服务器中的任何数据库调用该函数;否则,您可以任意命名该函数,并将其安装在数据所在的同一个数据库中(待比较)。
  • 第一次通过外部循环将@string2 1的各个组件与@string2 2的所有组件进行比较;第二次通过循环将@string2 2的各个组件与@string2 1的所有组件进行比较。
  • 我们在@目标字符串的末端附加一个“:”,以避免对@目标执行开始和结束字符串测试的需要。

函数的一些示例调用:

代码语言:javascript
复制
declare @string1 varchar(300),
        @string2 varchar(300),
        @string3 varchar(300),
        @string4 varchar(300),
        @string5 varchar(300)

select  @string1 = 'substring1:substring3:substring5',
        @string2 = 'substring3:substring1:substring5',

        @string3 = 'substring2:substring4:substring6',
        @string4 = 'substring6:substring2:substring4',

        @string5 = 'substring2:substring4:substring6:substring7'

select  dbo.sp_f_compare(@string1, @string2) as '1v2',
        dbo.sp_f_compare(@string3, @string4) as '3v4',
        dbo.sp_f_compare(@string1, @string3) as '1v3',
        dbo.sp_f_compare(@string3, @string5) as '3v5',
        dbo.sp_f_compare(@string5, @string3) as '5v3'
go

 1v2        3v4        1v3        3v5        5v3
 ---------- ---------- ---------- ---------- ----------
 pass       pass       fail       fail       fail

备注:

  • 在调用UDF时,必须包括UDF的所有者( 'dbo.‘’)。(以上示例中的前缀)

如果运行Sybase ASE 16,您可以访问表@变量。

当您仍然需要创建一个UDF时,表示UDF可以将2x输入字符串解析为表@变量,然后对2x表@变量运行一个基于集合的查询,以确定'pass‘或'fail’。

票数 0
EN

Stack Overflow用户

发布于 2017-06-23 18:34:47

UDF解决方案是我认为最适合经常重用的东西的解决方案。然而,就我的目的而言,我的努力程度只是略高于我想要投资的水平。因此,我跳过了一个动态的、干净的、高效的、自动的解决方案,并使用了一个强力的解决方案,可以归结为这样的逻辑:我有两个字符串,我想比较任何位置上的任何元素都可以存在于另一个字符串中的任何位置(元素是由一个冒号分隔的10个字符的子字符串)。这不是一个很好的循环或类似的东西,这是我的解决方案:

代码语言:javascript
复制
CASE 
        when substring(batch_ids, 1, 10) = substring(offers,1,10) then "PASS"
        when substring(batch_ids, 1, 10) = substring(offers,13,10) then "PASS"
        when substring(batch_ids, 1, 10) = substring(offers,24,10) then "PASS"
        when substring(batch_ids, 1, 10) = substring(offers,35,10) then "PASS"
        when substring(batch_ids, 13, 10) = substring(offers,1,10) then "PASS"
        when substring(batch_ids, 13, 10) = substring(offers,13,10) then "PASS"
        when substring(batch_ids, 13, 10) = substring(offers,24,10) then "PASS"
        when substring(batch_ids, 13, 10) = substring(offers,35,10) then "PASS"
        when substring(batch_ids, 24, 10) = substring(offers,1,10) then "PASS"
        when substring(batch_ids, 24, 10) = substring(offers,13,10) then "PASS"
        when substring(batch_ids, 24, 10) = substring(offers,24,10) then "PASS"
        when substring(batch_ids, 24, 10) = substring(offers,35,10) then "PASS"   
        when substring(batch_ids, 35, 10) = substring(offers,1,10) then "PASS"
        when substring(batch_ids, 35, 10) = substring(offers,13,10) then "PASS"
        when substring(batch_ids, 35, 10) = substring(offers,24,10) then "PASS"
        when substring(batch_ids, 35, 10) = substring(offers,35,10) then "PASS"else "FAIL"
    end as TestResults

从本质上讲,它接受第一列的第一个元素,从位置1开始的子字符串和长10个字符的子字符串(即1234567890),并将其与位置1-10、13-23、24-34和35-45中的第二个字符串的子字符串进行比较。然后根据第二列中相同的位置检查第一个字符串的第二个子字符串,依此类推。这确实意味着,如果我们有一个包含4个以上元素的字符串,那么它的维护就不太理想了,但目前的现实是,我们不会在很长一段时间内看到这一点,而且只有当我们对上游代码进行更改时,才需要进行冒烟测试。

虽然这个解决方案丑陋和不优雅,但是扩展是一个相当简单的copy+paste工作,并且在这里和那里改变了一些东西。

编辑:我可能有一些错误的起始位置,但是我的解决方案的基本要点是做a= b的子字符串,如果是这样的话,如果没有,那么继续前进,失败。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44594200

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档