从SQL Server 2008 R2中的多个值(列)中获取多行

时间:2017-07-06 15:58:22

标签: sql sql-server sql-server-2008 tsql sql-server-2008-r2

我有这张表

+-----+------+--------+--------+
| ID  | Name |  Start |   End  |
+-----+------+--------+--------+
| 20  | Mike |   1    |    3   |
| 21  | Luke |   4    |    7   |
+-----+------+--------+--------+ 

我想根据每个人的范围(开始/结束)生成所有行。

结果应该是

+-----+------+-----------------+
| ID  | Name |    Start_End    |
+-----+------+-----------------+
| 20  | Mike |        1        |
| 20  | Mike |        2        |
| 20  | Mike |        3        |
| 21  | Luke |        4        |
| 21  | Luke |        5        |
| 21  | Luke |        6        |
| 21  | Luke |        7        |
+-----+------+--------+--------+ 

要根据“开始”和“结束”列获取唯一值,我有此功能

CREATE FUNCTION [dbo].[ufn_SplitRange] (@Start INT, @End INT)  
RETURNS TABLE  
AS  
RETURN   
(  
    SELECT  TOP (@End - @Start+1) ROW_NUMBER() OVER (ORDER BY S.[object_id])+(@Start - 1) [Start_End]
    FROM    sys.all_objects S WITH (NOLOCK)
); 

以上函数返回(基于Mike范围1-3)的输出:

1
2
3

我一直在尝试几种方法,我找不到合适的解决方案,这似乎是一项非常常见的任务,但却是一项棘手的工作。

非常感谢任何输入

3 个答案:

答案 0 :(得分:2)

使用cross apply()

select t.Id, t.Name, x.Start_End
from t
  cross apply dbo.ufn_SplitRange(t.Start,t.[End]) as x

rextester演示:http://rextester.com/FVA48693

返回:

+----+------+-----------+
| Id | Name | Start_End |
+----+------+-----------+
| 20 | Mike |         1 |
| 20 | Mike |         2 |
| 20 | Mike |         3 |
| 21 | Luke |         4 |
| 21 | Luke |         5 |
| 21 | Luke |         6 |
| 21 | Luke |         7 |
+----+------+-----------+

答案 1 :(得分:1)

您可以使用以下计数表:

IncorporationDate

输出:

import csv
import requests

COMPANY_URLS = [
    'http://business.data.gov.uk/id/company/01046514.json',
    'http://business.data.gov.uk/id/company/01751318.json',
    'http://business.data.gov.uk/id/company/03164710.json',
    'http://business.data.gov.uk/id/company/04403406.json',
    'http://business.data.gov.uk/id/company/04405987.json',
]

def get_company_data():
    for url in COMPANY_URLS:
        res = requests.get(url)
        if res.status_code == 200:
             yield res.json()

if __name__ == '__main__':
    for data in get_company_data():
        try:
            incorporation_date = data['primaryTopic']['IncorporationDate']
        except KeyError:
            continue
        else:
            with open('out.csv', 'a') as csvfile:
                writer = csv.writer(csvfile)
                writer.writerow([incorporation_date])

答案 2 :(得分:0)

您可以像这样使用recursive cte

DECLARE @SampleData AS TABLE 
(
    Id int,
    Name varchar(10),
    Start int,
    [End] int
)

INSERT INTO @SampleData
(
    Id,
    Name,
    Start,
    [End]
)
VALUES
(1,'Mike',1,3),
(2,'Luke',4,7)

;WITH temp AS
(
    SELECT Id, sd.Name, sd.Start , sd.[End]
    FROM @SampleData sd

    UNION ALL

    SELECT t.Id, t.Name, t.Start + 1, t.[End]
    FROM temp t
    WHERE t.Start < t.[End]
)
SELECT t.Id, t.Name, t.Start AS [Start_End]
FROM temp t
ORDER BY t.Id
OPTION (MAXRECURSION 0)

演示链接:http://rextester.com/AFNYFW81782