2015-05-18 24 views
2

我試圖在Microsoft SQL Server 2012中用T-SQL生成乘法表,並且在寬度大於高度的情況下卡住了。只要它不成立,一切都會順利,但任何時候高度都會更大,所有指數大於最後一個高度值的單元格都是NULL ...爲什麼這樣以及如何才能克服這個問題?使用T-SQL生成乘法表

它只是生成值方陣了,從我的理解高度,但我真的不知道如何解決它......

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

OUT:

X 2 3 4 5 
2 4 NULL NULL NULL 
+1

你想要的結果是什麼?向我們展示矩陣的高度3和寬度5例如 –

+0

在TSQL中創建逗號分隔的字符串做一些研究。你在做什麼是相當可疑的。提示:使用適當的軟件(MySQL,Oracle,DB2,...)和版本(例如, '的SQL服務器2014'。語法和功能的差異往往會影響答案。 – HABO

回答

1

我沒真的不看你的代碼,我只寫了我自己的代碼,它適用於任何高度或寬度。檢查出來:

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 
0

這裏是一個不同的版本:

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

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

X 2 3 4 5 
2 4 6 8 10 
3 6 9 12 15 

@InitialValue INT = 5,@height INT = 4,@width INT = 3

X 5 6 
2 10 12 
3 15 18 
4 20 24 
+0

謝謝,但你是否試圖使用SQL Server 2012運行它?原因在我的電腦上輸出「來自'的關鍵字附近的語法錯誤'。」關於最後的命令。我是否在嘗試運行它或者在2012版本中有什麼錯誤? – Straightfw

+0

@Straightfw,這是因爲變量被聲明爲varhcar(100),這對於大數組是不夠的。只需更改爲4000。 –