繁体   English   中英

在 t-sql 中格式化查询结果

[英]Formatting query results in t-sql

这是我当前的代码,它从给定数字开始生成 2 个乘法表:

CREATE
    OR

ALTER PROCEDURE dbo.math_tables (@x INT = 1)
AS
BEGIN
    DECLARE @y INT = 1
    DECLARE @ctr INT = 0

    BEGIN
        WHILE @ctr <= 2
        BEGIN
            WHILE @y <= 10
            BEGIN
                 PRINT ltrim(str(@x)) + ' x ' + ltrim(str(@y)) + ' = ' + ltrim(str(@x * @y))

                SET @y += 1
            END

            SET @x += 1
            SET @y = 1
            SET @ctr += 1

            PRINT '---------------------------'
        END
    END
END
GO

EXECUTE dbo.math_tables 5 /* Starting table */
GO

结果目前看起来像这样一个接一个:

5 x 1 = 5
5 x 2 = 10
5 x 3 = 15
5 x 4 = 20
5 x 5 = 25
5 x 6 = 30
5 x 7 = 35
5 x 8 = 40
5 x 9 = 45
5 x 10 = 50
---------------------------
6 x 1 = 6
6 x 2 = 12
6 x 3 = 18
6 x 4 = 24
6 x 5 = 30
6 x 6 = 36
6 x 7 = 42
6 x 8 = 48
6 x 9 = 54
6 x 10 = 60
---------------------------

但我希望它看起来像这样。 基本上,每当@ctr 上升一个时,我都会尝试从一个新专栏开始:

5 x 1 = 5      6 x 1 = 6
5 x 2 = 10     6 x 2 = 12
5 x 3 = 15     6 x 3 = 18
5 x 4 = 20     6 x 4 = 24
5 x 5 = 25     6 x 5 = 30
5 x 6 = 30     6 x 6 = 36
5 x 7 = 35     6 x 7 = 42
5 x 8 = 40     6 x 8 = 48
5 x 9 = 45     6 x 9 = 54
5 x 10 = 50    6 x 10 = 60

请不要问为什么......我正在尝试学习查询结果格式以提高可读性;D

根据您的要求,您需要 go 和临时/物理表。 选择任何你能选择的。 否则你需要根据你的结果集编写一些字符串操作操作。

我已经根据我的理解修改了查询。 并确认我要使用表格方法。

    DECLARE @x INT = 5
    DECLARE @y INT = 1
    DECLARE @ctr INT = 0
    DECLARE @Value NVARCHAR(200)
    DECLARE @SQL NVARCHAR(MAX)
    CREATE Table #Matrix
    (
        Id INT IDENTITY(1,1)
    )
    BEGIN
        WHILE @ctr <= 2     
        BEGIN
            EXEC('ALTER TABLE #Matrix ADD COL_'+@ctr+' NVARCHAR(200)')
            WHILE @y <= 10
            BEGIN
                 SET @Value = ltrim(str(@x)) + ' x ' + ltrim(str(@y)) + ' = ' + ltrim(str(@x * @y))
                 IF(@ctr>0)
                 BEGIN
                    SET @SQL = CONCAT('UPDATE #Matrix SET [COL_',CAST(@ctr AS NVARCHAR),']=''',@Value,''' WHERE Id = ',@y)
                 END
                 ELSE
                 BEGIN
                    SET @SQL = CONCAT('INSERT INTO #Matrix([COL_',CAST(@ctr AS NVARCHAR),']) VALUES(''',@Value,''')')
                 END                 
                 EXEC(@SQL)
                SET @y += 1
            END

            SET @x += 1
            SET @y = 1
            SET @ctr += 1
            
        END
    END
    SELECT * FROM #Matrix
    DROP TABLE #Matrix

Output

在此处输入图像描述

在查询中,我添加了一个表,即#Matrix在表中,我们在循环执行时添加了一次列。

将列添加到表后,我们将数据插入/更新到表中。

正如@Lamu 所建议的,这是一种无需循环或递归的方法。 在 2022 年,您可以将“Tally”cte 替换为 GENERATE_SERIES(),或者,如果有的话,您可以使用数字/Tally 表或基于 function 的集合,例如 Itzik Ben-Gan 的“GetNums”function 或我的“fnTally”function .

并且,一点integer除法和Modulo做数据的“定位”。 请记住,模数返回除法的“余数”,当被除数和除数都是整数时,商和余数也将是整数。

   WITH
cteTally AS
(--==== Generate a psuedo Tally Table from 1 to 11.
     -- We'll have a separating bar show up at 11.
 SELECT TOP (11)
        N = ROW_NUMBER() OVER (ORDER BY @@SPID) --Used for both the Multiplicand and Multiplier
   FROM      sys.all_columns ac1
  CROSS JOIN sys.all_columns ac2
)
,cteMultiply AS
(--==== Create the display value for each product combination and a row# to derive Grp, Col, and Row from.
     -- The CROSS JOIN is also known as a "Cartesian Product" or "Square Join", like a times table.
 SELECT  RowNum = ROW_NUMBER() OVER (ORDER BY t1.N,t2.N)-1
        ,DisplayValue   = CONCAT(CONVERT(CHAR(3),t1.N),'x ',CONVERT(CHAR(3),t2.N),'= ',t1.N*t2.N)
   FROM      cteTally t1 --Multiplicand
  CROSS JOIN cteTally t2 --Multiplier
)--==== This is what is known as a "CROSSTAB".
 SELECT  Col1 = MAX(CASE 
                    WHEN Row = 10 THEN REPLICATE('-',13)
                    WHEN Col =  0 THEN DisplayValue
                    END)
        ,Col2 = MAX(CASE 
                    WHEN Row = 10 THEN REPLICATE('-',13)
                    WHEN Col =  1 THEN DisplayValue
                    END)
   FROM cteMultiply m
  CROSS APPLY (VALUES(RowNum/22, RowNum/11%2,RowNum%11))ca(Grp,Col,Row) --"DRY" it out.
  WHERE RowNum < 110
  GROUP BY ca.Grp, ca.Row
  ORDER BY ca.Grp, ca.Row
;

做整个 10*10 的事情让我有点忘乎所以。 代码应该很容易修改以适应。 这是结果集......

Col1           Col2
1  x 1  = 1    2  x 1  = 2
1  x 2  = 2    2  x 2  = 4
1  x 3  = 3    2  x 3  = 6
1  x 4  = 4    2  x 4  = 8
1  x 5  = 5    2  x 5  = 10
1  x 6  = 6    2  x 6  = 12
1  x 7  = 7    2  x 7  = 14
1  x 8  = 8    2  x 8  = 16
1  x 9  = 9    2  x 9  = 18
1  x 10 = 10   2  x 10 = 20
-------------  -------------
3  x 1  = 3    4  x 1  = 4
3  x 2  = 6    4  x 2  = 8
3  x 3  = 9    4  x 3  = 12
3  x 4  = 12   4  x 4  = 16
3  x 5  = 15   4  x 5  = 20
3  x 6  = 18   4  x 6  = 24
3  x 7  = 21   4  x 7  = 28
3  x 8  = 24   4  x 8  = 32
3  x 9  = 27   4  x 9  = 36
3  x 10 = 30   4  x 10 = 40
-------------  -------------
5  x 1  = 5    6  x 1  = 6
5  x 2  = 10   6  x 2  = 12
5  x 3  = 15   6  x 3  = 18
5  x 4  = 20   6  x 4  = 24
5  x 5  = 25   6  x 5  = 30
5  x 6  = 30   6  x 6  = 36
5  x 7  = 35   6  x 7  = 42
5  x 8  = 40   6  x 8  = 48
5  x 9  = 45   6  x 9  = 54
5  x 10 = 50   6  x 10 = 60
-------------  -------------
7  x 1  = 7    8  x 1  = 8
7  x 2  = 14   8  x 2  = 16
7  x 3  = 21   8  x 3  = 24
7  x 4  = 28   8  x 4  = 32
7  x 5  = 35   8  x 5  = 40
7  x 6  = 42   8  x 6  = 48
7  x 7  = 49   8  x 7  = 56
7  x 8  = 56   8  x 8  = 64
7  x 9  = 63   8  x 9  = 72
7  x 10 = 70   8  x 10 = 80
-------------  -------------
9  x 1  = 9    10 x 1  = 10
9  x 2  = 18   10 x 2  = 20
9  x 3  = 27   10 x 3  = 30
9  x 4  = 36   10 x 4  = 40
9  x 5  = 45   10 x 5  = 50
9  x 6  = 54   10 x 6  = 60
9  x 7  = 63   10 x 7  = 70
9  x 8  = 72   10 x 8  = 80
9  x 9  = 81   10 x 9  = 90
9  x 10 = 90   10 x 10 = 100
-------------  -------------

如果你可以在没有破折号的情况下生活,那就更容易了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM