2011-08-03 30 views
1

我需要关于此问题的帮助。我需要创建一个函数来接受一个整数并从输入值开始返回一个10x10的乘法表。SQL Server:创建乘法表

样品可以在下面看到。

INPUT = 2 OUTPUT =

2 3 4 5 6 7 8 9 10 11 
2 4 6 8 10 12 14 16 18 20 22 
3 6 9 12 15 18 21 24 27 30 33 
4 8 12 16 20 24 28 32 36 40 44 
5 10 15 20 25 30 35 40 45 50 55 
6 12 18 24 30 36 42 48 54 60 66 
7 14 21 28 35 42 49 56 63 70 77 
8 16 24 32 40 48 56 64 72 80 88 
9 18 27 36 45 54 63 72 81 90 99 
10 20 30 40 50 60 70 80 90 100 110 
11 22 33 44 55 66 77 88 99 110 121 
+1

谷歌递归CTE –

+1

为什么你需要这样做?它闻起来像我的功课。 – mwigdahl

+5

你为什么要在SQL服务器上做这件事? –

回答

1

试试这个:

DECLARE @StartNumber int 
     ,@EndNumber int 
SELECT @StartNumber=2 
     ,@[email protected]tartNumber+9 

;WITH AllNumbers AS 
(
    SELECT @StartNumber AS Number 
     , @StartNumber*(@StartNumber+0) AS Number1 
     , @StartNumber*(@StartNumber+1) AS Number2 
     , @StartNumber*(@StartNumber+2) AS Number3 
     , @StartNumber*(@StartNumber+3) AS Number4 
     , @StartNumber*(@StartNumber+4) AS Number5 
     , @StartNumber*(@StartNumber+5) AS Number6 
     , @StartNumber*(@StartNumber+6) AS Number7 
     , @StartNumber*(@StartNumber+7) AS Number8 
     , @StartNumber*(@StartNumber+8) AS Number9 
     , @StartNumber*(@StartNumber+9) AS Number10 
    UNION ALL 
    SELECT Number+1 
     , (Number+1)*(@StartNumber+0) AS Number1 
     , (Number+1)*(@StartNumber+1) AS Number2 
     , (Number+1)*(@StartNumber+2) AS Number3 
     , (Number+1)*(@StartNumber+3) AS Number4 
     , (Number+1)*(@StartNumber+4) AS Number5 
     , (Number+1)*(@StartNumber+5) AS Number6 
     , (Number+1)*(@StartNumber+6) AS Number7 
     , (Number+1)*(@StartNumber+7) AS Number8 
     , (Number+1)*(@StartNumber+8) AS Number9 
     , (Number+1)*(@StartNumber+9) AS Number10 

     FROM AllNumbers 
     WHERE Number<@EndNumber 
) 
SELECT * FROM AllNumbers a 

OUTPUT:

Number Number1 Number2 Number3 Number4 Number5 Number6 Number7 Number8 Number9 Number10 
------- ------- ------- ------- ------- ------- ------- ------- ------- ------- -------- 
2  4  6  8  10  12  14  16  18  20  22 
3  6  9  12  15  18  21  24  27  30  33 
4  8  12  16  20  24  28  32  36  40  44 
5  10  15  20  25  30  35  40  45  50  55 
6  12  18  24  30  36  42  48  54  60  66 
7  14  21  28  35  42  49  56  63  70  77 
8  16  24  32  40  48  56  64  72  80  88 
9  18  27  36  45  54  63  72  81  90  99 
10  20  30  40  50  60  70  80  90  100  110 
11  22  33  44  55  66  77  88  99  110  121 

(10 row(s) affected) 

使动态SQL来获取正确的列名:

DECLARE @SQL varchar(5000) 
     ,@StartNumber int 
SET @StartNumber=2 
SET @SQL=' 
DECLARE @StartNumber int 
     ,@EndNumber int 
SELECT @StartNumber='+CONVERT(varchar(3),@StartNumber)+' 
     ,@[email protected]+9 

;WITH AllNumbers AS 
(
    SELECT @StartNumber AS [ ] 
     , @StartNumber*(@StartNumber+0) AS ['+CONVERT(varchar(3),@StartNumber+0)+'] 
     , @StartNumber*(@StartNumber+1) AS ['+CONVERT(varchar(3),@StartNumber+1)+'] 
     , @StartNumber*(@StartNumber+2) AS ['+CONVERT(varchar(3),@StartNumber+2)+'] 
     , @StartNumber*(@StartNumber+3) AS ['+CONVERT(varchar(3),@StartNumber+3)+'] 
     , @StartNumber*(@StartNumber+4) AS ['+CONVERT(varchar(3),@StartNumber+4)+'] 
     , @StartNumber*(@StartNumber+5) AS ['+CONVERT(varchar(3),@StartNumber+5)+'] 
     , @StartNumber*(@StartNumber+6) AS ['+CONVERT(varchar(3),@StartNumber+6)+'] 
     , @StartNumber*(@StartNumber+7) AS ['+CONVERT(varchar(3),@StartNumber+7)+'] 
     , @StartNumber*(@StartNumber+8) AS ['+CONVERT(varchar(3),@StartNumber+8)+'] 
     , @StartNumber*(@StartNumber+9) AS ['+CONVERT(varchar(3),@StartNumber+9)+'] 
    UNION ALL 
    SELECT [ ]+1 
     , ([ ]+1)*(@StartNumber+0) AS ['+CONVERT(varchar(3),@StartNumber+0)+'] 
     , ([ ]+1)*(@StartNumber+1) AS ['+CONVERT(varchar(3),@StartNumber+1)+'] 
     , ([ ]+1)*(@StartNumber+2) AS ['+CONVERT(varchar(3),@StartNumber+2)+'] 
     , ([ ]+1)*(@StartNumber+3) AS ['+CONVERT(varchar(3),@StartNumber+3)+'] 
     , ([ ]+1)*(@StartNumber+4) AS ['+CONVERT(varchar(3),@StartNumber+4)+'] 
     , ([ ]+1)*(@StartNumber+5) AS ['+CONVERT(varchar(3),@StartNumber+5)+'] 
     , ([ ]+1)*(@StartNumber+6) AS ['+CONVERT(varchar(3),@StartNumber+6)+'] 
     , ([ ]+1)*(@StartNumber+7) AS ['+CONVERT(varchar(3),@StartNumber+7)+'] 
     , ([ ]+1)*(@StartNumber+8) AS ['+CONVERT(varchar(3),@StartNumber+8)+'] 
     , ([ ]+1)*(@StartNumber+9) AS ['+CONVERT(varchar(3),@StartNumber+9)+'] 

     FROM AllNumbers 
     WHERE [ ]<@EndNumber 
) 
SELECT * FROM AllNumbers a' 

exec(@SQL) 

OUTPUT:

 2 3 4 5 6 7 8 9 10 11 
------ ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- 
2  4 6 8 10 12 14 16 18 20 22 
3  6 9 12 15 18 21 24 27 30 33 
4  8 12 16 20 24 28 32 36 40 44 
5  10 15 20 25 30 35 40 45 50 55 
6  12 18 24 30 36 42 48 54 60 66 
7  14 21 28 35 42 49 56 63 70 77 
8  16 24 32 40 48 56 64 72 80 88 
9  18 27 36 45 54 63 72 81 90 99 
10  20 30 40 50 60 70 80 90 100 110 
11  22 33 44 55 66 77 88 99 110 121 

(10 row(s) affected) 
0

这里有一个交叉连接解决方​​案为您提供:

DECLARE @StartNum int; 
SET @StartNum = 1; 

WITH numbers AS (
    SELECT 
    N = @StartNum + number 
    FROM master..spt_values 
    WHERE type = 'P' 
    AND number BETWEEN 0 AND 9 
), 
products AS (
    SELECT 
    n1.N, 
    PivotN = n2.N, 
    P = n1.N * n2.N 
    FROM numbers n1 
    CROSS JOIN numbers n2 
) 
SELECT 
    N, 
    P0 = MAX(CASE PivotN WHEN @StartNum + 0 THEN P END), 
    P1 = MAX(CASE PivotN WHEN @StartNum + 1 THEN P END), 
    P2 = MAX(CASE PivotN WHEN @StartNum + 2 THEN P END), 
    P3 = MAX(CASE PivotN WHEN @StartNum + 3 THEN P END), 
    P4 = MAX(CASE PivotN WHEN @StartNum + 4 THEN P END), 
    P5 = MAX(CASE PivotN WHEN @StartNum + 5 THEN P END), 
    P6 = MAX(CASE PivotN WHEN @StartNum + 6 THEN P END), 
    P7 = MAX(CASE PivotN WHEN @StartNum + 7 THEN P END), 
    P8 = MAX(CASE PivotN WHEN @StartNum + 8 THEN P END), 
    P9 = MAX(CASE PivotN WHEN @StartNum + 9 THEN P END) 
FROM products 
GROUP BY N 
ORDER BY N 

像与松下的解决方案,可以改写上述查询有动态的列名,但你将无法在TVF中使用结果查询。一个存储过程可以。下面是相同脚本的动态版本:

DECLARE @StartNum int, @NumColumns varchar(max), @sql varchar(max); 
SET @StartNum = 2; 

SELECT 
    @NumColumns = COALESCE(@NumColumns + ', ', '') 
       + '[' + CAST(@StartNum + number AS varchar) + ']' 
FROM master..spt_values 
WHERE type = 'P' 
    AND number BETWEEN 0 AND 9; 

SET @sql = 
'WITH numbers AS (
    SELECT ' + CAST(@StartNum AS varchar) + ' + number AS N 
    FROM master..spt_values 
    WHERE type = ''P'' 
    AND number BETWEEN 0 AND 9 
), 
products AS (
    SELECT 
    n1.N, 
    PivotN = n2.N, 
    P = n1.N * n2.N 
    FROM numbers n1 
    CROSS JOIN numbers n2 
) 
SELECT 
    N, ' + @NumColumns + ' 
FROM products 
PIVOT (MAX(P) FOR PivotN IN (' + @NumColumns + ')) p'; 
EXEC(@sql);