简体   繁体   English

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

[英]Formatting query results in t-sql

This is my current code that generate 2 multiplication tables starting from a given number:这是我当前的代码,它从给定数字开始生成 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

The results currently look like this one after the other:结果目前看起来像这样一个接一个:

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

But I want it to look like this.但我希望它看起来像这样。 Basically I'm trying to start from a new column every-time @ctr goes up by one:基本上,每当@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

Please don't ask why... I'm trynna learn query result formatting for readability;D请不要问为什么......我正在尝试学习查询结果格式以提高可读性;D

As per your requirement, you need to go with Temp/physical table.根据您的要求,您需要 go 和临时/物理表。 Choose whatever you can choose it.选择任何你能选择的。 else you need to write some string manipulation operations more as per your result set.否则你需要根据你的结果集编写一些字符串操作操作。

I've modified the query as per my understanding.我已经根据我的理解修改了查询。 and confirm that I'm going with table approaches.并确认我要使用表格方法。

    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 Output

在此处输入图像描述

In the query, I added one table namely #Matrix In the table, we are adding the columns once while the loop executing.在查询中,我添加了一个表,即#Matrix在表中,我们在循环执行时添加了一次列。

Once a column is added to the table we insert/update the data into a table.将列添加到表后,我们将数据插入/更新到表中。

As @Lamu suggested, here's a way to do it without loops or recursion.正如@Lamu 所建议的,这是一种无需循环或递归的方法。 In 2022, you can replace the "Tally" cte with GENERATE_SERIES() or, if you have one, you can use you a Numbers/Tally table or set based function like Itzik Ben-Gan's "GetNums" function or my "fnTally" function.在 2022 年,您可以将“Tally”cte 替换为 GENERATE_SERIES(),或者,如果有的话,您可以使用数字/Tally 表或基于 function 的集合,例如 Itzik Ben-Gan 的“GetNums”function 或我的“fnTally”function .

And, a little integer division and Modulo do the "positioning" of the data.并且,一点integer除法和Modulo做数据的“定位”。 Remember that Modulus returns the "Remainder" for division and that when both the Dividend and the Divisor are integers, so will be the Quotient and the Remainder.请记住,模数返回除法的“余数”,当被除数和除数都是整数时,商和余数也将是整数。

   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
;

I got a bit carried away with doing the whole 10*10 thing.做整个 10*10 的事情让我有点忘乎所以。 The code should be fairly easy to modify to suit.代码应该很容易修改以适应。 Here's the result set from that...这是结果集......

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

If you can live without the dashes, it gets even easier.如果你可以在没有破折号的情况下生活,那就更容易了。

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

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