SQL Server:创建乘法表

时间:2011-08-03 14:51:28

标签: sql-server user-defined-functions

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

示例见下文。

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

3 个答案:

答案 0 :(得分:1)

试试这个:

DECLARE @StartNumber int
       ,@EndNumber   int
SELECT @StartNumber=2
      ,@EndNumber=@StartNumber+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

输出:

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)+'
      ,@EndNumber=@StartNumber+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)

输出:

       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)

答案 1 :(得分: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

与KM的解决方案一样,可以重写上述查询以获得动态列名,但是您将无法在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);

答案 2 :(得分:0)

试试这个:-

DECLARE @InitialValue int =2, @Height int =10, @Width int =10, @ColumnNames varchar(max), @RowNames varchar(max), @sql varchar(max);

SELECT @RowNames = @RowNames + '[' + CAST(@InitialValue + number AS varchar) + ']'
FROM master..spt_values WHERE type = 'P' AND number BETWEEN 0 AND @Height-2

SELECT @ColumnNames = COALESCE(@ColumnNames + ', ', '') + '[' + CAST(@InitialValue + number AS varchar) + ']'
FROM master..spt_values WHERE type = 'P' AND number BETWEEN 0 AND @Width-2

SET @sql =
'WITH numbers AS ( SELECT ' + CAST(@InitialValue AS varchar) + ' + number AS X FROM master..spt_values WHERE type = ''P''
    AND number BETWEEN 0 AND ' + CAST(@Height-2 AS varchar) +'
),
products AS (
  SELECT n1.X, PivotN = n2.X, P = n1.X * n2.X FROM numbers n1 CROSS JOIN numbers n2
)
SELECT X, ' + @ColumnNames + '
FROM products
PIVOT (MAX(P) FOR PivotN IN (' + @ColumnNames + ')) p'
EXEC(@sql)

-----------------------------------------------------------------------