[英]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.