Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.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 Server如何检索2个数字之间的所有数字_Sql_Sql Server_Sql Server 2008 - Fatal编程技术网

SQL Server如何检索2个数字之间的所有数字

SQL Server如何检索2个数字之间的所有数字,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,我有4列-代码、金额、开始、结束。我想在开始列和结束列之间取金额,并将其更改为包含所有结果的一列。对如何实现这一目标有何建议?谢谢 Current Results: Code Amount Start End 1 5000 2015 2016 2 5000 2014 2016 3 20000 2012 2016 Desired Results: Code Amount StartEnd 1 5000 2015 1

我有4列-代码、金额、开始、结束。我想在开始列和结束列之间取金额,并将其更改为包含所有结果的一列。对如何实现这一目标有何建议?谢谢

Current Results:
Code  Amount  Start  End
1     5000    2015   2016
2     5000    2014   2016
3     20000   2012   2016

Desired Results:
Code  Amount  StartEnd
1     5000    2015
1     5000    2016
2     5000    2014
2     5000    2015
2     5000    2016
3     20000   2012
3     20000   2013
3     20000   2014
3     20000   2015
3     20000   2016

您可以使用递归cte生成最小开始和最大结束之间的所有数字,并在生成的数字上进行连接

with cte as (select min(start) col,max(end) mx from tablename
             union all
             select col+1,mx from cte where col < mx)
select t.code,t.amount,c.col
from cte c
join tablename t on c.col between t.start and t.end 
或者更简单地说

with cte as (select id,amount,start startend,end from tablename
             union all
             select id,amount,start+1,end from cte where start<end)
select id,amount,startend
from cte
order by 1,3

另一个选择是UDF。我使用这个TVF来生成动态范围

Declare @YourTable table (Code  int, Amount int,  Start int , [End] int)
Insert into @YourTable values 
(1,5000 ,2015,2016),
(2,5000 ,2014,2016),
(3,20000,2012,2016)

Select A.Code
      ,A.Amount
      ,StartEnd = cast(B.RetVal as int)
 From @YourTable A
 Cross Apply (Select * from [dbo].[udf-Range-Number](A.Start,A.[End],1)) B
返回

Code    Amount  StartEnd
1       5000    2015
1       5000    2016
2       5000    2014
2       5000    2015
2       5000    2016
3       20000   2012
3       20000   2013
3       20000   2014
3       20000   2015
3       20000   2016
功能

CREATE FUNCTION [dbo].[udf-Range-Number] (@R1 money,@R2 money,@Incr money)
Returns Table
Return (
    with cte0(M) As (Select cast((@R2-@R1)/@Incr as int)),
         cte1(N) As (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N)),
         cte2(N) As (Select Top (Select M from cte0) Row_Number() over (Order By (Select NULL)) From cte1 a,cte1 b,cte1 c,cte1 d,cte1 e,cte1 f,cte1 g,cte1 h )

    Select RetSeq=1,RetVal=@R1 Union All Select N+1,(N*@Incr)+@R1
    From   cte2   
)
/*
Max 100 million observations -- 
Syntax:
Select * from [dbo].[udf-Range-Number](0,4,0.25)
*/

我不确定它是否适用于SQL 2008,但这里有一个CTE:

;with sel_cte as (
select Code, Amount, start StartEnd
from @tblTest t

union all

select t.code, t.amount, c.StartEnd + 1 StartEnd
from sel_cte c
  inner join @tblTest t on t.code = c.code
where c.StartEnd + 1 <= [end]
)
select *
from sel_cte
order by Code, StartEnd

注:将@tblTest替换为实际的表名。

如果要求只允许您有连续的数字,如2014、2015、2016等,则上述cte方法可以正常工作。但是,如果没有,您可以创建另一个临时表,比如说数字,它有一列,数字按照您想要的结果输出的连续顺序排列,比如

Number
2014
2015
2016
2018 <-- Missing 2017 and jumping on 2018
2019

您可以这样查询

SELECT
    c.code,
    c.amount,
    f.yr
FROM #code c
CROSS APPLY fn_yearslist(c.startyr, c.endyr) f
CREATE FUNCTION fn_yearslist (@startyear int, @endyear int)
RETURNS @t TABLE (
    yr int
)
AS
BEGIN
    WHILE (@startyear <= @endyear)
    BEGIN
    INSERT INTO @t (yr)
        VALUES (@startyear)
    SET @startyear += 1
    END
    RETURN
END
您可以这样创建函数

SELECT
    c.code,
    c.amount,
    f.yr
FROM #code c
CROSS APPLY fn_yearslist(c.startyr, c.endyr) f
CREATE FUNCTION fn_yearslist (@startyear int, @endyear int)
RETURNS @t TABLE (
    yr int
)
AS
BEGIN
    WHILE (@startyear <= @endyear)
    BEGIN
    INSERT INTO @t (yr)
        VALUES (@startyear)
    SET @startyear += 1
    END
    RETURN
END

哪个版本的sql server?对不起,现在是2008年。也许我错了。。。左连接意味着如果有年份没有值,那么将有一行只有最后一列和null,所以我猜它一直到最后一列op@Hogan .. 这里不需要左连接。右连接,除非他想显示没有任何范围的年份。我没有看到两件事1这与OP明确说明的问题有什么关系检索2个数字之间的所有数字表示连续的数字。2您提到,如果需要,您可以填充另一个临时表,但您没有显示任何方法,也没有讨论它的逻辑。也许您认为cte方法将获取表的最大值和最小值,并生成所有数字。所以,如果有中断,比如说第3行,从2009年开始到2012年结束,那么您将丢失2013年的数据?但cte实际上也可以忽略2013年,另一个表格的方法可能会在未来引入跳过数字的额外灵活性。我忽略了创建和插入单列表的细节,因为我假设具有连续数字的单列表应该易于创建和填充。此外,使用cte方法忽略或跳过一个数字需要硬编码。抱歉,但我来自一个完整的堆栈背景有所有这些想法固有的。