Извините за этот вводящий в заблуждение предмет, я не знал, как лучше сказать.Поскольку я в основном разработчик программного обеспечения, троичный оператор приходит мне на ум с моей следующей проблемой:
Мне нужно найти самый надежный способ связать две таблицы через обнуляемый внешний ключ (modModel
иtabSparePart
).Единственное сходство между ними - это название модели и описание запасной части (tabSparePart
- это внешняя таблица от клиента, которая импортируется автоматически, поэтому я не несу ответственности и не могу изменить данные).
Рассмотрим следующие имена запасных частей:
W200I_E/Swap
EXCHANGEUNIT P1i / SILVERBLACK/ CYRILLIC
Имена моделей, которые я хочу найти: P1i
и W200I_E
.Таким образом, в where-clause
:
- должно быть только одно строгое правило: должен быть разделитель
/
, а соответствующая часть - первая.
Вот пример данных:
Create table #temp(Partname varchar(100))
INSERT INTO #temp
SELECT 'EXCHANGEUNIT P1i / SILVERBLACK/ CYRILLIC' UNION ALL SELECT 'W200I_E/Swap unit/Black'
Я бы закончил следующий запрос:
SELECT RTRIM(LEFT(Partname, CHARINDEX('/', Partname) - 1)) AS UNIT
FROM #temp
WHERE CHARINDEX('/', Partname) > 0
... что возвращает:
EXCHANGEUNIT P1i
W200I_E
Но мне нужно P1i
.Поэтому мне нужен способ справиться и с тем случаем, что первая часть отделена пробелами.В этом случае мне нужно выбрать последнее слово, но только если оно отделено .
Я получаю ошибку "invalid length parameter passed to the LEFT or SUBSTRING function"
со следующим запросом:
SELECT REVERSE( LEFT( REVERSE(RTRIM(LEFT(Partname, CHARINDEX('/', Partname) - 1)))
, CHARINDEX(' ', REVERSE(RTRIM(LEFT(Partname, CHARINDEX('/', Partname) - 1))))-1 ))
AS Unit
FROM #temp
WHERE CHARINDEX('/', Partname) > 0
Это будет работать без второй записи без пробелов.Если бы я также гарантировал, что первая часть содержит пробелы, я бы отбросил действительные записи.
Короче говоря, мне нужно найти способ объединить оба способа в соответствии с существованием разделителей.
PS: Это возникло из: Получить последнее слово части varchar (ВЛЕВО / ВПРАВО)
Если кому-то интересно, этополная (рабочая) хранимая процедура.Я уверен, что никогда не использовал такой странный JOIN
:
CREATE PROC [dbo].[UpdateModelSparePart](@updateCount int output)
with execute as Owner
AS
BEGIN
BEGIN TRANSACTION
UPDATE modModel SET fiSparePart=ModelPart.idSparePart
FROM modModel INNER JOIN
(
SELECT m.idModel
,m.ModelName
,sp.idSparePart
,sp.Price
,Row_Number()Over(Partition By idModel ORDER BY Price DESC)as ModelPrice
FROM modModel AS m INNER JOIN tabSparePart AS sp
ON m.ModelName = CASE
WHEN CHARINDEX(' ', REVERSE(RTRIM(LEFT(sp.SparePartDescription, CHARINDEX('/', sp.SparePartDescription) - 1)))) > 0 THEN
REVERSE( LEFT( REVERSE(RTRIM(LEFT(sp.SparePartDescription, CHARINDEX('/', sp.SparePartDescription) - 1)))
,CHARINDEX(' ', REVERSE(RTRIM(LEFT(sp.SparePartDescription, CHARINDEX('/', sp.SparePartDescription) - 1))))-1 ))
ELSE
RTRIM(LEFT(sp.SparePartDescription, CHARINDEX('/', sp.SparePartDescription) - 1))
END
WHERE (CHARINDEX('/', sp.SparePartDescription) > 0)
GROUP BY idModel,ModelName,idSparePart,Price
)As ModelPart
ON ModelPart.idModel=modModel.idModel
Where ModelPrice=1
SET @updateCount = @@ROWCOUNT;
COMMIT TRANSACTION
END