【问题标题】:Selecting records that have a prefix选择有前缀的记录
【发布时间】:2021-09-13 18:53:35
【问题描述】:

我是 SQL Server 新手,需要帮助编写查询

我收到了大约 400 个看起来像(123456、1234555、342345 等)的身份证号码。我应该从具有这些 id 的表中选择所有记录。问题是引用这些 id (ActionIDreference) 的列在其某些值 (A123456,A1234555,A342345) 前面有一个前缀 (A)。有时它(ActionIDreference)没有“A”。我需要考虑该列中引用这些特定 ID 的任何变化。

我希望能够从列中提取这 400 个 id,无论它前面有 A 还是没有 A,然后没有它。

表格名称是 ActionReport。

我正在使用 Sql Server

希望问题很清楚。

感谢您的帮助

【问题讨论】:

  • 提问时,您需要提供minimal reproducible example: (1) DDL 和样本数据填充,即 CREATE 表和 INSERT T-SQL 语句。 (2) 你需要做什么,即逻辑和你的代码尝试在 T-SQL 中实现它。 (3) 期望的输出,基于上面#1 中的样本数据。 (4) 您的 SQL Server 版本 (SELECT @@version;)。全部在问题内,没有图片。

标签: sql sql-server select case


【解决方案1】:

您可以使用 replace() 函数首先从所有 ID 中删除“A”,然后与带有 in 的 ID 列表进行比较。

 select * fromActionReport
 where replace(ActionIDreference,'A','')in (123456, 1234555, 342345 )

另一种方法是使用union allstuff()

 select * fromActionReport
 where ActionIDreference like 'A%' and STUFF(ActionIDreference,1,1,'') in (123456, 1234555, 342345 )

 union all

 select * fromActionReport
 where ActionIDreference not like 'A%' ActionIDreference in (123456, 1234555, 342345 )

创建一个表来保存您要搜索的 ActionIDreference 值。然后将 400 个 ID 插入其中。

create table search_criterion (ActionIDreference varchar(20));
insert into search_criterion values('123456'), ('1234555'), ('342345'), ('123456');

现在您不知道表中哪些值具有“A”作为前缀,因此您将复制所有行并重新插入带有前缀“A”的表中。

insert into search_criterion select 'A'+ActionIDreference from search_criterion;

现在您的实际查询将是:

 select * fromActionReport
 where ActionIDreference in (select ActionIDreference from search_criterion  );

【讨论】:

  • 谢谢你。运行此查询需要花费大量时间,目前已超过 15 分钟且仍在执行
  • 更新:抛出“System.OutOfMemoryException”错误
  • 表格有多少行?您尝试了哪种方法?
  • 表中有大约一百万条记录。我尝试了这两种方法。
  • 我刚刚测试了一个包含近 1 亿行的表,它需要将近三分钟。我正在修改我的答案,这会更快,但需要一些额外的工作。
【解决方案2】:

只需使用in 并涵盖所有可能性:

where ActionIDreference in ('123456', '1234555', '342345', '123456', 'A1234555', 'A342345')

任何其他方法都可能导致查询计划不理想。是的,SQL Server 可以处理 IN 列表中的 800 个值——生成 800 个值应该不会比生成 400 个更难。

【讨论】:

    【解决方案3】:

    试试下面的。创建一个临时表来保存您的 id 值

    Create table #temp (Id varchar(10) not null primary key) /* data type should match the target table*/
    

    插入您的值列表

    Insert into #temp values ('123456'),('345678'),...
    

    更新您的表格并使用“A”前缀

    update #temp set Id='A' + Id
    

    现在重复您的第一次插入,以便您的表格以带有和不带有“A”前缀的值列表结束。

    现在运行与临时表连接的查询

    select a.*
    from #temp t
    join fromActionReport a on a.ActionIDreference=t.Id
    

    【讨论】:

      【解决方案4】:

      您可以加载带有 id 值和带有 A 前缀的 id 值的表变量。

      DECLARE @table table(id varchar(10))
      
      -- insert without prefix
      insert into @table
      SELECT cast(id as varchar(10)) as id FROM (VALUES ('12345'),('13345')) as t(id)
      -- insert with prefix
      insert into @table
      SELECT cast(CONCAT('A',id) as varchar(10)) FROM  @table
      

      现在,您可以在主表中为表变量中的 id 应用 IN 条件

      SELECT * FROM ActionReport where ActionReportIDReference IN
      (
      Select id from @table) 
      

      【讨论】:

        猜你喜欢
        • 2012-02-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-24
        • 1970-01-01
        • 2016-08-11
        • 2020-07-21
        • 2023-03-11
        相关资源
        最近更新 更多