【发布时间】:2017-05-04 15:06:04
【问题描述】:
版本:Microsoft SQL Server 2014 - 12.0.2000.8 (X64) Feb 20 2014 20:04:26 版权所有 (c) Microsoft Corporation Express Edition (64-bit) on Windows NT 6.1 (Build 7601: Service Pack 1)
我需要从表中选择不同数量的值,其中某一列等于一个参数,并且某一列是 LIKE 'String1' 或 'String2'。
我创建了一个返回 MAX 和 MIN 字符串的存储过程,但这个方法自然不是动态的。
我尝试了以下查询,它说它成功完成,但没有返回任何结果。
SELECT UPC, PartNum, PartDesc
FROM dbo.table
WHERE UPC = @upc
GROUP BY UPC, PartNum, PartDesc
HAVING PartDesc in ('%RED%','%BLUE%')
ORDER BY PartDesc;
示例表:
ID UPC PartNum PartDesc
-------------------------------------------
1 123 543 Red1
2 123 345 Blue1
3 123 654 Red2
4 123 765 Blue2
我需要从应用程序将参数作为@upc 传递给存储过程。
它将在哪里找到类似于“%RED%”或“%BLUE%”的任何 PartDesc,并且 UPC = @upc。 然后将找到的 Part#(s) 存储在新表中以供稍后查询。
从存储过程创建表:
ID UPC Red1 Red2 Blue1 Blue2
----------------------------------------------------------
1 123 543 654 345 765
每个 UPC 编号可以有任意数量或“红色”或“蓝色”的组合。 IE。, 一些 UPC 编号可能只有两个“红色”部分和一个“蓝色”部分,而其他 UPC 编号可能只有两个“红色”部分而没有“蓝色”部分。也许五个“红色”部分和十个“蓝色”部分。
如何编写将不同数量的找到结果存储到存储过程中的新表的查询?
编辑 似乎应该使用 PIVOT 函数,但我不确定如何在我的场景中使用所需的聚合。为此,我不需要关注 PartDesc 的“SUM”或任何其他列。 也许是动态枢轴?
编辑基于 Corgi 的建议。另外,展示我的作品。
DECLARE @upc As varchar(13)
DECLARE @Red1 As nvarchar(100) = CASE
WHEN
(
SELECT MIN(PartNum) FROM dbo.table
WHERE PartDesc LIKE '%RED%' AND UPC = @upc
) IS NOT NULL THEN
(
SELECT MIN(PartNum) FROM dbo.table
WHERE PartDesc LIKE '%RED%' AND UPC = @upc
)
ELSE 'Not Found'
END
DECLARE @Red2 As nvarchar(100) = CASE
WHEN
(
SELECT MAX(PartNum) FROM dbo.table
WHERE PartDesc LIKE '%RED%' AND UPC = @upc
) IS NOT NULL THEN
(
SELECT MAX(PartNum) FROM dbo.table
WHERE PartDesc LIKE '%RED%' AND UPC = @upc
)
ELSE 'Not Found'
END
DECLARE @Blue1 As nvarchar(100) = CASE
WHEN
(
SELECT MAX(PartNum) FROM dbo.table
WHERE PartDesc LIKE '%BLUE%' AND UPC = @upc
) IS NOT NULL THEN
(
SELECT MAX(PartNum) FROM dbo.table
WHERE PartDesc LIKE '%BLUE%' AND UPC = @upc
)
ELSE 'Not Found'
END
;WITH MostColumns AS
(
SELECT UPC, @Red1 As Part1, @Red2 As Part2, @Blue1 As Part3
FROM (SELECT UPC, PartNum, PartDesc
FROM dbo.table) AS source
PIVOT
(MIN(PartNum) FOR PartDesc IN ([Part1], [Part2], [Part3])) AS pvt
)
SELECT MIN(p.ID) AS ID, p.UPC, mc.Part1, mc.Part2, mc.Part3
INTO MyNewTable
FROM dbo.table p
INNER JOIN MostColumns mc ON p.UPC = mc.UPC
GROUP BY p.UPC, mc.Part1, mc.Part2, mc.Part3
结果:
ID UPC Part1 Part2 Part3
2876 123 Not Found Not Found Not Found
2758 213 Not Found Not Found Not Found
2321 312 Not Found Not Found Not Found
802 321 Not Found Not Found Not Found
868 132 Not Found Not Found Not Found
这是正确的格式,但不是雪茄。我知道一个事实,我所有的 UPC 至少包含一个 Red1 部分。由于某种原因,它没有找到任何部件。
编辑--回答 @Corgi 在对动态枢轴进行更多研究后,我得出了这个解决方案。我仍然需要在它的基础上进行构建,以使其按照我需要的方式运行。虽然,这些与这个问题无关。 感谢@bluefeet 在这篇文章中的回答。 SQL Dynamic Pivot
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ','
+ QUOTENAME('Part_' + cast(rn as varchar(10)))
from dbo.table
cross apply
(
select row_number() over(partition by UPC order by PartNum) rn
from dbo.table
) x
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT UPC, ' + @cols + ' from
(
select UPC, PartNum,
''Component_''
+ cast(row_number() over(partition by UPC order by PartNum) as varchar(10)) val
from dbo.table
) x
pivot
(
max(PartNum)
for val in (' + @cols + ')
) p '
execute(@query)
【问题讨论】:
标签: sql-server stored-procedures pivot sql-server-2014-express