Версия: Microsoft SQL Server 2014 — 12.0.2000.8 (X64) 20 февраля 2014 г. 20:04:26 Авторские права (c) Microsoft Corporation Express Edition (64-разрядная версия) для Windows NT 6.1 (сборка 7601: пакет обновления 1)
Мне нужно выбрать различное количество значений из таблицы, где определенный столбец равен параметру, а определенный столбец похож на «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 из приложения.
Где он найдет любой PartDesc, похожий на «% RED%» или «% BLUE%» И где UPC = @upc. Затем сохраните найденные номера частей в новой таблице для последующего запроса.
Созданная таблица из хранимой процедуры:
ID UPC Red1 Red2 Blue1 Blue2
----------------------------------------------------------
1 123 543 654 345 765
Для каждого номера UPC может быть любое количество или комбинация «красного» или «синего». т. е. некоторые номера UPC могут иметь только две «красные» части и одну «синюю» часть, а другие могут иметь только две «красные» части и не иметь «синих» частей. Может быть, пять «красных» частей и десять «синих».
Как мне написать запрос, который будет хранить различное количество найденных результатов в новой таблице в хранимой процедуре?
Изменить Кажется, что должна использоваться функция PIVOT, но я не знаю, как использовать требуемый агрегат в моем сценарии. Мне не нужно ориентироваться на «СУММУ» PartDesc или любого другого столбца в этом отношении. Возможно, динамический Pivot?
ИЗМЕНИТЬ На основе рекомендации Корги. Также показываю свои работы.
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
Это правильный формат, но не сигара. Я точно знаю, что все мои БЗК содержат как минимум одну Red1
часть. Почему-то не нашел ни одной части.
EDIT--ANSWER @Corgi После дополнительных исследований динамических поворотов я пришел к этому решению. Мне все еще нужно будет доработать его, чтобы заставить его работать так, как мне нужно. Хотя, они не имеют отношения к этому вопросу. Спасибо @bluefeet за ваш ответ в этом посте. Динамический свод SQL
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)