Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.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生成列指定范围之间的数字_Sql_Sql Server_Oracle - Fatal编程技术网

SQL生成列指定范围之间的数字

SQL生成列指定范围之间的数字,sql,sql-server,oracle,Sql,Sql Server,Oracle,我有一张像这样的桌子 IDNUM | Name | LowRange | HighRange | Notes 123 | TESTS | 100 | 201 | Hello 124 | TEST2 | 200 | 210 | 125 | TESTS | 100 | 201 | Hello 我想知道是否有一个查询会返回以下结果 IDNUM | Name | Number | Notes 123 | TESTS

我有一张像这样的桌子

IDNUM | Name  | LowRange | HighRange | Notes
123   | TESTS | 100      | 201       | Hello
124   | TEST2 | 200      | 210       | 
125   | TESTS | 100      | 201       | Hello
我想知道是否有一个查询会返回以下结果

IDNUM | Name  | Number | Notes
123   | TESTS | 100      | Hello
123   | TESTS | 101      | Hello
123   | TESTS | 102      | Hello
123   | TESTS | 103      | Hello
......til 201
124   | TEST2 | 200      | 
124   | TEST2 | 201      |
124   | TEST2 | 202      |  
......til 210 

我正在寻找一种在SQL server 2016和Oracle 11g中都能做到这一点的方法,但任何一种方法的帮助都将不胜感激

最简单的方法是数字表。以下内容在Oracle和SQL Server中都适用-假设数字的基表足够大:

with numbers as (
      select row_number() over (order by idnum) - 1 as n
      from t
     )
select idnum, name, lowrange + n.n as number, notes
from t join
     numbers n
     on lowrange + n.n <= highrange;
如果上面生成的数字不够,您可以在CTE中使用交叉连接来获得更多


每个数据库都有生成数字的可选方法,但这在两个数据库中都有效。

最简单的方法是数字表。以下内容在Oracle和SQL Server中都适用-假设数字的基表足够大:

with numbers as (
      select row_number() over (order by idnum) - 1 as n
      from t
     )
select idnum, name, lowrange + n.n as number, notes
from t join
     numbers n
     on lowrange + n.n <= highrange;
如果上面生成的数字不够,您可以在CTE中使用交叉连接来获得更多


每个数据库都有生成数字的替代方法,但这在两个数据库中都有效。

一种方法是使用中的代码并使用以下代码:

DECLARE @startnum INT
DECLARE @endnum INT

SELECT  @startnum = MIN(LowRange) ,
        @endnum = MAX(HighRange)
FROM    IDsAndRanges

;
WITH gen AS (
    SELECT @startnum AS num
    UNION ALL
    SELECT num+1 FROM gen WHERE num+1<=@endnum
)

SELECT  * 
FROM    [IDsAndRanges] I
LEFT
JOIN    gen G
        ON G.num BETWEEN I.LowRange AND I.HighRange
option (maxrecursion 10000)

一种方法是在中使用代码并使用以下内容:

DECLARE @startnum INT
DECLARE @endnum INT

SELECT  @startnum = MIN(LowRange) ,
        @endnum = MAX(HighRange)
FROM    IDsAndRanges

;
WITH gen AS (
    SELECT @startnum AS num
    UNION ALL
    SELECT num+1 FROM gen WHERE num+1<=@endnum
)

SELECT  * 
FROM    [IDsAndRanges] I
LEFT
JOIN    gen G
        ON G.num BETWEEN I.LowRange AND I.HighRange
option (maxrecursion 10000)

您可以将其作为递归with子句(也称为recursive CTE)来执行,如下所示:

WITH main_data (idnum, NAME, NUM, highrange, notes) AS (SELECT idnum,
                                                               NAME,
                                                               lowrange NUM,
                                                               highrange,
                                                               notes
                                                        FROM   sample_data
                                                        UNION ALL
                                                        SELECT idnum,
                                                               NAME,
                                                               NUM + 1 NUM,
                                                               highrange,
                                                               notes
                                                        FROM   main_data
                                                       WHERE  NUM < highrange)
SELECT idnum,
       NAME,
       NUM,
       notes
FROM   main_data
ORDER BY idnum, NUM;


     IDNUM NAME         NUM NOTES
---------- ----- ---------- -----
       123 TESTS        100 Hello
       123 TESTS        101 Hello
       123 TESTS        102 Hello
       123 TESTS        103 Hello
       124 TEST2        200 
       124 TEST2        201 
       124 TEST2        202 
       124 TEST2        203 
       124 TEST2        204 
       125 TESTS        150 Hello
       125 TESTS        151 Hello
       125 TESTS        152 Hello
       125 TESTS        153 Hello
       125 TESTS        154 Hello
       125 TESTS        155 Hello
       125 TESTS        156 Hello
       125 TESTS        157 Hello
       125 TESTS        158 Hello
       125 TESTS        159 Hello
       125 TESTS        160 Hello

您可以将其作为递归with子句(也称为recursive CTE)来执行,如下所示:

WITH main_data (idnum, NAME, NUM, highrange, notes) AS (SELECT idnum,
                                                               NAME,
                                                               lowrange NUM,
                                                               highrange,
                                                               notes
                                                        FROM   sample_data
                                                        UNION ALL
                                                        SELECT idnum,
                                                               NAME,
                                                               NUM + 1 NUM,
                                                               highrange,
                                                               notes
                                                        FROM   main_data
                                                       WHERE  NUM < highrange)
SELECT idnum,
       NAME,
       NUM,
       notes
FROM   main_data
ORDER BY idnum, NUM;


     IDNUM NAME         NUM NOTES
---------- ----- ---------- -----
       123 TESTS        100 Hello
       123 TESTS        101 Hello
       123 TESTS        102 Hello
       123 TESTS        103 Hello
       124 TEST2        200 
       124 TEST2        201 
       124 TEST2        202 
       124 TEST2        203 
       124 TEST2        204 
       125 TESTS        150 Hello
       125 TESTS        151 Hello
       125 TESTS        152 Hello
       125 TESTS        153 Hello
       125 TESTS        154 Hello
       125 TESTS        155 Hello
       125 TESTS        156 Hello
       125 TESTS        157 Hello
       125 TESTS        158 Hello
       125 TESTS        159 Hello
       125 TESTS        160 Hello
Oracle分层查询:

递归子查询分解子句:

Oracle分层查询:

递归子查询分解子句:


也许这不是一个好方法,但对我来说很有效

CREATE TYPE shin.tab_rows AS OBJECT (
  idnum           NUMBER,
  description  VARCHAR2(50),
  num_ber  NUMBER,
  notes  VARCHAR2(50)
);
/

CREATE TYPE shin.test_tab IS TABLE OF shin.tab_rows;
/


CREATE OR REPLACE FUNCTION shin.get_numbers
 RETURN shin.test_tab PIPELINED AS
BEGIN
  for records in (select IDNUM,lowrange,highrange,name,notes from shin.test_stack) LOOP

  FOR num_ber IN records.lowrange..records.highrange LOOP
    PIPE ROW(shin.tab_rows(records.IDNUM, records.name,num_ber,records.notes));  

    END LOOP; 
  END LOOP;

  RETURN;
END;
/

select * from table(shin.get_numbers)

也许这不是一个好方法,但对我来说很有效

CREATE TYPE shin.tab_rows AS OBJECT (
  idnum           NUMBER,
  description  VARCHAR2(50),
  num_ber  NUMBER,
  notes  VARCHAR2(50)
);
/

CREATE TYPE shin.test_tab IS TABLE OF shin.tab_rows;
/


CREATE OR REPLACE FUNCTION shin.get_numbers
 RETURN shin.test_tab PIPELINED AS
BEGIN
  for records in (select IDNUM,lowrange,highrange,name,notes from shin.test_stack) LOOP

  FOR num_ber IN records.lowrange..records.highrange LOOP
    PIPE ROW(shin.tab_rows(records.IDNUM, records.name,num_ber,records.notes));  

    END LOOP; 
  END LOOP;

  RETURN;
END;
/

select * from table(shin.get_numbers)

使用理货台非常简单。这在Oracle和sql server中都适用,尽管您必须以稍微不同的方式构建它。然后,从表中选择并连接到tally表,其中tally.N>=LowRange和tally.N对于数字表来说是一个很好的用法,只是列中有整数的表。连接>=下限,使用计数表非常简单。这在Oracle和sql server中都适用,尽管您必须以稍微不同的方式构建它。然后,从表中选择并连接到tally表,其中tally.N>=LowRange和tally.N对于数字表来说是一个很好的用法,只是列中有整数的表。在>=低量程和