【问题标题】:TSQL to return what existsTSQL 返回存在的内容
【发布时间】:2021-10-15 05:52:07
【问题描述】:

这是对此的后续问题 TSQL to search text

我的情况如下

declare @vendor as table (vName varchar(max))
insert into @vendor
select *
from
(
    values
        ('Maccro'),
        ('Accro')
) t (one)

declare @transaction as table (descr varchar(max))
insert into @transaction
select *
from
(
    values
        ('recl Maccro something'),
        ('lrec Accro Maccro'),
        ('lrec Maccr0'),
        ('Maccro indeed'),
        ('ACCR Accro'),
        ('Raac else')
) t (one)

我可以运行以下查询

Select 
    a.descr,
    CASE WHEN EXISTS(select * From @vendor b
                     where Charindex(b.Vname, a.descr) > 0)
              then 1 else 0 End [doesContain]

from @transaction a

返回以下内容

| descr                 | doesContain |
| --------------------- | ----------- |
| recl Maccro something | 1           |
| lrec Accro Maccro     | 1           |
| lrec Maccr0           | 0           |
| Maccro indeed         | 1           |
| ACCR Accro            | 1           |
| Raac else             | 0           |

但是是否有可能看到它为 doesContain 返回 1 的值,即 @vendor 表中的什么值,Exists 返回匹配项。

我想要的输出如下

| descr                 | doesContain | containsWhat |
| --------------------- | ----------- | ------------ |
| recl Maccro something | 1           | Maccro       |
| lrec Accro Maccro     | 1           | Accro        |
| lrec Maccr0           | 0           |              |
| Maccro indeed         | 1           | Maccro       |
| ACCR Accro            | 1           | Accro        |
| Raac else             | 0           |              |

【问题讨论】:

  • containsWhat for 'lrec Accro Maccro' 也应该是 'Maccro'
  • 不是我,但我的猜测是“缺乏研究”——你似乎没有尝试过任何事情。
  • 感谢@DaleK。我不知道该怎么做才能解决这个问题。所以这可能被视为“缺乏研究”

标签: sql sql-server tsql join window-functions


【解决方案1】:

在供应商和交易之间使用叉积,然后使用 charindex 查看供应商名称是否在描述符中。如果您有多个供应商,这种方法效果很好。

declare @vendor as table (vName varchar(max))
insert into @vendor
select distinct *
from
(
values
    ('Maccro'),
    ('Accro')
) t (one)

declare @transaction as table (descr varchar(max))
insert into @transaction
select *
from
(
values
    ('recl Maccro something'),
    ('lrec Accro Maccro'),
    ('lrec Maccr0'),
    ('Maccro indeed'),
    ('ACCR Accro'),
    ('Raac else')
) t (one)

select trans.descr,vend.vName vName,
case when charindex(vend.vName,trans.descr)>0 then 1 else 0 end doesContain
from @transaction trans
cross apply @vendor vend
order by descr,vName

输出

ACCR Accro  Accro   1
ACCR Accro  Maccro  0
Maccro indeed   Accro   0
Maccro indeed   Maccro  1
Raac else   Accro   0
Raac else   Maccro  0
lrec Accro Maccro   Accro   1
lrec Accro Maccro   Maccro  1
lrec Maccr0 Accro   0
lrec Maccr0 Maccro  0
recl Maccro something   Accro   0
recl Maccro something   Maccro  1

【讨论】:

    【解决方案2】:

    如果您希望获得交易的供应商列表,您可以使用 external apply 和 string_agg 函数。

    Select 
    a.descr,
    Case When v.list Is Not Null Then 1 Else 0 End,
    v.list
    From @transaction a Outer Apply
        (Select String_AGG(b.vName,', ') As list From @vendor b
         Where PatIndex(Concat('% ',b.Vname,' %'), a.descr) > 0 Or
               PatIndex(Concat(b.Vname,' %'), a.descr) > 0 Or
               PatIndex(Concat('% ',b.Vname), a.descr) > 0) v
    

    【讨论】:

      【解决方案3】:

      使用 @transaction@vendorFIRST_VALUE() 窗口函数的 LEFT 连接来获得第一次出现:

      Select distinct
          a.descr,
          CASE WHEN b.Vname is not null then 1 else 0 End [doesContain],
          first_value(b.Vname) over (partition by a.descr order by Charindex(b.Vname, a.descr)) containsWhat 
      from @transaction a left join @vendor b
      on Charindex(b.Vname, a.descr) > 0
      

      请参阅demo

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-02-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多