首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用T-SQL生成乘法表

用T-SQL生成乘法表
EN

Stack Overflow用户
提问于 2015-05-19 03:51:59
回答 2查看 863关注 0票数 2

我试图在Microsoft SQL Server 2012中使用T-SQL生成乘法表,但遇到了宽度大于高度的情况。只要它不成立,一切顺利,但任何时候高度较大,所有索引大于上一个高度值的单元格都为空…为什么会这样呢?我该如何克服呢?

根据我的理解,它只是生成最高值的方阵,但我不太确定如何修复它……

代码语言:javascript
复制
DECLARE @InitialValue int, @Height int, @Width int, @ColumnNames varchar(max), @RowNames varchar(max), @sql varchar(max);
SET @InitialValue = 2;
SET @Height = 2
SET @Width = 5

SELECT
    @RowNames = COALESCE(@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);

输出:

代码语言:javascript
复制
X   2   3   4   5
2   4   NULL    NULL    NULL
EN

回答 2

Stack Overflow用户

发布于 2015-05-19 04:35:45

我并没有真正看过你的代码,我只是写了我自己的代码,它适用于任何高度和宽度。看看这个:

代码语言:javascript
复制
DECLARE @InitialValue INT = 1,
        @Height INT = 1,
        @Width INT  = 5,
        @PivotColumns VARCHAR(MAX);
IF OBJECT_ID('tempdb..##NumsTable') IS NOT NULL
    DROP TABLE ##numsTable;

CREATE TABLE ##NumsTable (num INT PRIMARY KEY);

WITH CTE_Nums
AS
(
    SELECT @InitialValue AS num
    UNION ALL
    SELECT num + 1
    FROM CTE_Nums
    WHERE num <=        CASE
                        WHEN @Height > @Width
                            THEN @Height
                        ELSE @Width
                    END
)

INSERT INTO ##numsTable
    SELECT num
    FROM CTE_Nums
    OPTION (MAXRECURSION 0)

SELECT @PivotColumns = COALESCE(@PivotColumns + ',','') + QUOTENAME(num)
FROM ##numsTable
WHERE num < @InitialValue + @Width;

DECLARE @SQL NVARCHAR(MAX);
SELECT @SQL = 
N'WITH CTE_crossJoin
AS
(
SELECT  A.num           AS rowNums,
        B.num           AS colNums,
        A.num * B.num   AS result
FROM ##numsTable A
CROSS JOIN ##numsTable B
WHERE       A.num < @IV + @H
        AND B.num < @IV+ @W
)

SELECT *
FROM CTE_crossJoin
PIVOT
(
    MAX(result) FOR colNums IN (' + @pivotColumns + ')
) pvt'

EXECUTE sp_executesql @sql,N'@IV INT,@H INT,@W INT', @IV = @initialValue,@H = @Height,@W = @Width
票数 1
EN

Stack Overflow用户

发布于 2015-05-19 05:03:09

下面是一个不同的版本:

代码语言:javascript
复制
declare @InitialValue int = 2, @Height int = 10, @Width int = 10;
declare @cols varchar(4000), @f varchar(4000), @s varchar(4000);

with cols as(select @InitialValue as w
            union all 
            select w + 1 from cols where w < @InitialValue + @Width - 1)

select 
      @cols = STUFF((SELECT '],[' + convert(varchar(10), w) FROM cols FOR XML PATH ('')) , 1, 2, '') + ']',
      @f = 'case when h.h = 1 then ''X'' else cast(h.h as char(10)) end,' + 
              STUFF((SELECT '],h.h*s.[' + convert(varchar(10), w) FROM cols FOR XML PATH ('')) , 1, 2, '') + ']'

set @s = 'with height as (
            select 1 as h
            union all 
            select h + 1 from height where h < ' + CAST(@Height as varchar(10)) +           
            '),
width as(select ' + CAST(@InitialValue as varchar(10)) + ' as w
            union all 
            select w + 1 from width where w < ' + CAST(@InitialValue + @Width - 1 as varchar(10)) +'),
spread as(select * from width pivot(max(w) for w in(' + @cols + ')) p)                      
select ' + @f + ' 
from height h
cross join spread s'

print (@s)
exec (@s)

输出:

@InitialValue int = 2,@Height int = 10,@Width int = 10

代码语言:javascript
复制
X   2   3   4   5   6   7   8   9   10
2   4   6   8   10  12  14  16  18  20
3   6   9   12  15  18  21  24  27  30
4   8   12  16  20  24  28  32  36  40
5   10  15  20  25  30  35  40  45  50
6   12  18  24  30  36  42  48  54  60
7   14  21  28  35  42  49  56  63  70
8   16  24  32  40  48  56  64  72  80
9   18  27  36  45  54  63  72  81  90
10  20  30  40  50  60  70  80  90  100

@InitialValue int = 2,@Height int = 3,@Width int = 5

代码语言:javascript
复制
X   2   3   4   5
2   4   6   8   10
3   6   9   12  15

@InitialValue int = 5,@Height int = 4,@Width int = 3

代码语言:javascript
复制
X   5   6
2   10  12
3   15  18
4   20  24
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30311699

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档