【问题标题】:SQL Server: create multiplication tableSQL Server:创建乘法表
【发布时间】:2011-08-03 14:51:28
【问题描述】:

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

示例如下。

输入 = 2 输出 =

    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

【问题讨论】:

  • 为什么需要这样做?这对我来说就像家庭作业。
  • 为什么要在 SQL Server 中这样做?
  • 我怎样才能使用交叉锄头?

标签: sql-server user-defined-functions


【解决方案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)

【讨论】:

    【解决方案2】:

    这是适合您的交叉连接解决方​​案:

    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);
    

    【讨论】:

      【解决方案3】:

      试试这个:-

      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)
      
      -----------------------------------------------------------------------
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-14
        • 2015-02-15
        相关资源
        最近更新 更多