sql - 具有有限列数的枢轴
问题描述
我在 Microsoft SQL 环境中遇到查询问题。由于客户的模板,我得到了我想从行转换为列的序列号。对我来说限制是客户的模板 - 最大列数可能是 10。我不知道如何达到我的愿景,即每 11-20、21-30 等列都将位于新行中。请参阅数据库中 13 行的示例:
我能做的:
产品01 | 产品02 | 产品03 | 产品04 | 产品05 | 产品06 | 产品07 | 产品08 | 产品09 | 产品10 | 产品11 | 产品12 | 产品13 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
BK018001B6 | BK018001B7 | BK018001B8 | BK018001B9 | BK018001BB | BK018001BC | BK018001BD | BK018001BF | BK018001BG | BK018001BH | BK018001BJ | BK018001BK | BK018001BL |
我想做的事:
产品01 | 产品02 | 产品03 | 产品04 | 产品05 | 产品06 | 产品07 | 产品08 | 产品09 | 产品10 |
---|---|---|---|---|---|---|---|---|---|
BK018001B6 | BK018001B7 | BK018001B8 | BK018001B9 | BK018001BB | BK018001BC | BK018001BD | BK018001BF | BK018001BG | BK018001BH |
BK018001BJ | BK018001BK | BK018001BL |
我发现以下适用于 Microsoft SQL 的工作场所:https ://sqlzoo.net/ 。不幸的是,没有办法为您提供工作场所作为链接。您需要复制我的 SQL 代码来重现:
CREATE TABLE #sourceTable(SerialNo VARCHAR(20), ProductRowNumber VARCHAR(10))
INSERT INTO #sourceTable
(
SerialNo,
ProductRowNumber
)
VALUES
('BK018001B6', 'Product01'),
('BK018001B7', 'Product02'),
('BK018001B8', 'Product03'),
('BK018001B9', 'Product04'),
('BK018001BB', 'Product05'),
('BK018001BC', 'Product06'),
('BK018001BD', 'Product07'),
('BK018001BF', 'Product08'),
('BK018001BG', 'Product09'),
('BK018001BH', 'Product10'),
('BK018001BJ', 'Product11'),
('BK018001BK', 'Product12'),
('BK018001BL', 'Product13')
CREATE TABLE #productsTempTable (ProductSerialNo VARCHAR(20), ProductRowNumber VARCHAR(10))
INSERT INTO #productsTempTable
SELECT SerialNo, ProductRowNumber FROM #sourceTable
DECLARE @cols AS NVARCHAR(MAX), @query AS NVARCHAR(MAX)
SELECT @cols = STUFF(
(SELECT ',' + QUOTENAME(ProductRowNumber)
FROM #productsTempTable
GROUP BY ProductRowNumber
ORDER BY ProductRowNumber
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
, 1, 1, '')
SET @query = N'SELECT ' + @cols + N' FROM
(
SELECT ProductSerialNo, ProductRowNumber
FROM #productsTempTable
) x
PIVOT
(
MAX(ProductSerialNo)
FOR ProductRowNumber IN (' + @cols + N')
) p'
EXEC sp_executesql @query;
DROP table #productsTempTable, #sourceTable
实际上,为了完整起见,我正在以这种方式撰写“ProductRowNumber”列:
'Product' + RIGHT(100 + CONVERT(VARCHAR(10), ROW_NUMBER() OVER(ORDER BY p.id)), 2) AS 'ProductRowNumber'
你能帮我解决这个问题吗?
谢谢你。
解决方案
这个枢轴不需要是动态的。我们只需要对行号进行一些算术运算:
SELECT
Product01, Product02, Product03, Product04, Product05, Product06, Product07, Product08, Product09, Product10
FROM (
SELECT
SerialNo,
rn10 = (ROW_NUMBER() OVER (ORDER BY ProductRowNumber) - 1) / 10,
ProductRN = CONCAT(
'Product',
FORMAT((ROW_NUMBER() OVER (ORDER BY ProductRowNumber) - 1) % 10 + 1, '00'))
FROM #sourceTable st
) st
PIVOT (
MAX(SerialNo) FOR ProductRN IN
(Product01, Product02, Product03, Product04, Product05, Product06, Product07, Product08, Product09, Product10)
) pvt;
在您的实际查询中,您可以将 替换为ROW_NUMBER
现有的行编号。
推荐阅读
- c# - 在 C# 中是否可以通过反射检查方法是否是迭代器?
- phaser-framework - Phaser 3 - 设置图形对象的锚点
- java - 如何使用 forEach() 方法通过 Java 8 迭代 AWS 预留 EC2 实例?
- react-native - React modal 元素不覆盖屏幕的左侧
- javascript - 在 redux saga 中使用 setTimeOut 内的 yield
- angular - 如果已经定义了两个字段,则 ngx-formly 自动填充三个字段之一
- javascript - 列出所有产品
- c# - Google Calendar API + Azure + 间歇性连接超时
- c++ - 使用 alexnet 和 cv::imread 图像推理 pytorch C++
- wordpress - 当我点击我的产品时,它会使用 Wordpress 网站重定向到主页