Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/87.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 搜索数字是否包含在表达式中,如:1-3,5,10-15,20_Sql_Regex_Oracle - Fatal编程技术网

Sql 搜索数字是否包含在表达式中,如:1-3,5,10-15,20

Sql 搜索数字是否包含在表达式中,如:1-3,5,10-15,20,sql,regex,oracle,Sql,Regex,Oracle,在oracle数据库表中,我需要找到给定批号的结果。 保存批号的字段是一个字符串,其中包含类似“1-3,5,10-15,20”的内容(此字符串中的数字已排序) 有没有办法做到这一点 在上述示例中,应找到以下批号的结果: 1,2,3,5,10,11,12,13,14,15,20 在应用程序中无法执行此操作,因此必须在数据库中执行 类似于:“从lot=2的产品中选择*”如果必须只使用SQL,这是最简单的解决方案。如果使用PL/SQL,则有更多的解决方案。但这可能是最有效和最简单的。当然,这里不是硬

在oracle数据库表中,我需要找到给定批号的结果。 保存批号的字段是一个字符串,其中包含类似“1-3,5,10-15,20”的内容(此字符串中的数字已排序)

有没有办法做到这一点

在上述示例中,应找到以下批号的结果:

1,2,3,5,10,11,12,13,14,15,20
在应用程序中无法执行此操作,因此必须在数据库中执行


类似于:“从lot=2的产品中选择*”

如果必须只使用SQL,这是最简单的解决方案。如果使用PL/SQL,则有更多的解决方案。但这可能是最有效和最简单的。当然,这里不是硬编码的数字,而是您的字符串:

SELECT * FROM products WHERE lot IN (Replace('1-3,5,10-15,20', '-', ',') )
/
如果需要,可以删除/替换字符串中的更多字符。上面的示例仅将“-”替换为“,”

问题是如何做到这一点:

"SELECT * FROM products WHERE lot = 2..."
不是这个:

1-3,
2,
4
...

清楚地陈述您的问题/示例。

如果您必须只使用SQL,这是最简单的解决方案。如果使用PL/SQL,则有更多的解决方案。但这可能是最有效和最简单的。当然,这里不是硬编码的数字,而是您的字符串:

SELECT * FROM products WHERE lot IN (Replace('1-3,5,10-15,20', '-', ',') )
/
如果需要,可以删除/替换字符串中的更多字符。上面的示例仅将“-”替换为“,”

问题是如何做到这一点:

"SELECT * FROM products WHERE lot = 2..."
不是这个:

1-3,
2,
4
...

清楚地陈述您的问题/示例。

这是T-SQL,但移植起来应该不难

DECLARE @ranges NVARCHAR(MAX);
DECLARE @number INT;

SET @ranges = N'1-3,5,10-15,20';
SET @number = 13;

DECLARE @found BIT;
DECLARE @commaIndex INT;
DECLARE @dashIndex INT;
DECLARE @range NVARCHAR(MAX);
DECLARE @rangeStart INT;
DECLARE @rangeEnd INT;

SET @found = 0;

SET @commaIndex = CHARINDEX(',', @ranges);

WHILE (@commaIndex > 0) BEGIN

  SET @range = SUBSTRING(@ranges, 1, @commaIndex - 1);

  SET @dashIndex = CHARINDEX('-', @range);

  IF (@dashIndex > 0) BEGIN

     SET @rangeStart = CAST(SUBSTRING(@range, 1, @dashIndex - 1) AS INT);
     SET @rangeEnd = CAST(SUBSTRING(@range, @dashIndex + 1, LEN(@range) - @dashIndex) AS INT);

  END ELSE BEGIN

     SET @rangeStart = CAST(@range AS INT);
     SET @rangeEnd = @rangeStart;

  END;

  IF ((@rangeStart <= @number) AND (@number <= @rangeEnd)) BEGIN

    SET @found = 1;

    BREAK;

  END;

  SET @ranges = SUBSTRING(@ranges, @commaIndex + 1, LEN(@ranges) - @commaIndex);
  SET @commaIndex = CHARINDEX(',', @ranges);

END;

IF (@found = 1) BEGIN

    PRINT N'Contained.';

END ELSE BEGIN

    PRINT N'Not contained.';

END;
声明@ranges NVARCHAR(最大值);
声明@number INT;
设置范围=N'1-3,5,10-15,20';
设置@number=13;
声明@found位;
声明@commaIndex INT;
声明@dashIndex INT;
声明@range NVARCHAR(最大值);
声明@rangeStart INT;
声明@rangeEnd INT;
设置@found=0;
设置@commaIndex=CHARINDEX(',',@范围);
当(@commaIndex>0)开始时
设置@range=SUBSTRING(@ranges,1,@commaIndex-1);
设置@dashIndex=CHARINDEX('-',@range);
如果(@dashIndex>0)开始
将@rangeStart=CAST(子字符串(@range,1,@dashIndex-1)设置为INT);
将@rangeEnd=CAST(子字符串(@range,@dashIndex+1,LEN(@range)-@dashIndex)设置为INT);
结束,否则开始
设置@rangeStart=CAST(@range为INT);
设置@rangeEnd=@rangeStart;
终止

IF((@rangeStart这是T-SQL,但它应该不难移植

DECLARE @ranges NVARCHAR(MAX);
DECLARE @number INT;

SET @ranges = N'1-3,5,10-15,20';
SET @number = 13;

DECLARE @found BIT;
DECLARE @commaIndex INT;
DECLARE @dashIndex INT;
DECLARE @range NVARCHAR(MAX);
DECLARE @rangeStart INT;
DECLARE @rangeEnd INT;

SET @found = 0;

SET @commaIndex = CHARINDEX(',', @ranges);

WHILE (@commaIndex > 0) BEGIN

  SET @range = SUBSTRING(@ranges, 1, @commaIndex - 1);

  SET @dashIndex = CHARINDEX('-', @range);

  IF (@dashIndex > 0) BEGIN

     SET @rangeStart = CAST(SUBSTRING(@range, 1, @dashIndex - 1) AS INT);
     SET @rangeEnd = CAST(SUBSTRING(@range, @dashIndex + 1, LEN(@range) - @dashIndex) AS INT);

  END ELSE BEGIN

     SET @rangeStart = CAST(@range AS INT);
     SET @rangeEnd = @rangeStart;

  END;

  IF ((@rangeStart <= @number) AND (@number <= @rangeEnd)) BEGIN

    SET @found = 1;

    BREAK;

  END;

  SET @ranges = SUBSTRING(@ranges, @commaIndex + 1, LEN(@ranges) - @commaIndex);
  SET @commaIndex = CHARINDEX(',', @ranges);

END;

IF (@found = 1) BEGIN

    PRINT N'Contained.';

END ELSE BEGIN

    PRINT N'Not contained.';

END;
声明@ranges NVARCHAR(最大值);
声明@number INT;
设置范围=N'1-3,5,10-15,20';
设置@number=13;
声明@found位;
声明@commaIndex INT;
声明@dashIndex INT;
声明@range NVARCHAR(最大值);
声明@rangeStart INT;
声明@rangeEnd INT;
设置@found=0;
设置@commaIndex=CHARINDEX(',',@范围);
当(@commaIndex>0)开始时
设置@range=SUBSTRING(@ranges,1,@commaIndex-1);
设置@dashIndex=CHARINDEX('-',@range);
如果(@dashIndex>0)开始
将@rangeStart=CAST(子字符串(@range,1,@dashIndex-1)设置为INT);
将@rangeEnd=CAST(子字符串(@range,@dashIndex+1,LEN(@range)-@dashIndex)设置为INT);
结束,否则开始
设置@rangeStart=CAST(@range为INT);
设置@rangeEnd=@rangeStart;
终止

如果(@rangeStart可以在SQL中使用函数和:

然而,我必须强调的是,正确地规范化数据库是一条可行之路。此解决方案可能无法很好地扩展,并且需要做大量不必要的工作

它的工作原理如下:

首先在逗号上拆分数据:

SQL>  select regexp_substr('1-3,5,10-15,20', '[^,]+', 1, level) as a
  2     from dual
  3  connect by regexp_substr('1-3,5,10-15,20', '[^,]+', 1, level) is not null
  4          ;

A
--------------
1-3
5
10-15
20
接下来,在连接到表之前,在连字符上拆分它,以提供一个最小和最大批次,以便在中间使用。NVL用于确保始终存在一个最大批次

SQL> select regexp_substr(a, '[[:digit:]]+',1, 1) as lot1
  2       , nvl( regexp_substr(a, '(-)([[:digit:]]+)',1, 1, 'i', '2')
  3             , regexp_substr(a, '[[:digit:]]+',1, 1)) as lot2
  4    from (select regexp_substr('1-3,5,10-15,20' , '[^,]+', 1, level) as a
  5            from dual
  6         connect by regexp_substr('1-3,5,10-15,20' , '[^,]+', 1, level) is not null
  7                 )
  8         ;

LOT1           LOT2
-------------- --------------
1              3
5              5
10             15
20             20

SQL>

下面是一个完整查询的处理过程。

可以使用函数和以下命令在SQL中完成这一切:

然而,我必须强调的是,正确地规范化数据库是一条可行之路。此解决方案可能无法很好地扩展,并且需要做大量不必要的工作

它的工作原理如下:

首先在逗号上拆分数据:

SQL>  select regexp_substr('1-3,5,10-15,20', '[^,]+', 1, level) as a
  2     from dual
  3  connect by regexp_substr('1-3,5,10-15,20', '[^,]+', 1, level) is not null
  4          ;

A
--------------
1-3
5
10-15
20
接下来,在连接到表之前,在连字符上拆分它,以提供一个最小和最大批次,以便在中间使用。NVL用于确保始终存在一个最大批次

SQL> select regexp_substr(a, '[[:digit:]]+',1, 1) as lot1
  2       , nvl( regexp_substr(a, '(-)([[:digit:]]+)',1, 1, 'i', '2')
  3             , regexp_substr(a, '[[:digit:]]+',1, 1)) as lot2
  4    from (select regexp_substr('1-3,5,10-15,20' , '[^,]+', 1, level) as a
  5            from dual
  6         connect by regexp_substr('1-3,5,10-15,20' , '[^,]+', 1, level) is not null
  7                 )
  8         ;

LOT1           LOT2
-------------- --------------
1              3
5              5
10             15
20             20

SQL>
这是一个完整查询的解决方案。

这是一个具有以下功能的解决方案:

查询:

select * from table(x_tbl('22-27,33,444-448'));
结果:

22
23
24
25
26
27
33
444
445
446
447
448
因此,您可以:

 select 1 from dual where 23 in (select * from  table(x_tbl('22-27,33,444-448')));
这是一个具有以下功能的解决方案:

查询:

select * from table(x_tbl('22-27,33,444-448'));
结果:

22
23
24
25
26
27
33
444
445
446
447
448
因此,您可以:

 select 1 from dual where 23 in (select * from  table(x_tbl('22-27,33,444-448')));

你需要一个SQL的唯一解决方案吗?或者你可以在你的应用程序中编码它吗?虽然第一个可能是可能的,但是它并不是最干净的数据库解决方案。考虑把数据插入一个预先分析的格式,比如你的“后续批号”。什么是<代码>结果行< /代码>?你想找什么?你是在请求一个SQL唯一的解决方案吗?还是你可以在你的应用程序中编码它呢?第一个可能的话,它并不是最干净的数据库解决方案。考虑把数据插入一个预先分析的格式,比如你的“后续批号”。line.what是
结果行
?您想查找什么?我不是SQL专家,但我很确定这不会起作用。如果您将所有破折号转换为逗号,则删除了“范围”指示符。
2
应该匹配
1-3
,但不能匹配
1,3
@Tim,您不能在SQL中写入范围,例如1-3中的某个内容…有效语法是Select…其中某个内容('1'、'2'、'3')或“…其中某个内容=1或某个内容=2…”。嗯,是的。这就是重点,不是吗?您的SQL查询如何匹配“2”?-1我是SQL方面的专家,这显然不能回答这个问题。你可能还想记住不要把事情看得太过个人化(没有人对你投反对票)。问题从一开始就存在:“在上面的例子中,应该找到以下批号的结果(或结果行):1,2,3,5,10,11,12,13,14,15,20”。您的示例将“-”替换为“,”,但找不到作为示例给出的“2”。此外,问题从一开始就被标记为[oracle],正如您所指出的,P