#sql #concatenation
#sql #конкатенация
Вопрос:
Я не могу выполнить конкатенацию в приведенном ниже примере! Когда я выполняю цикл, я получаю 2 правильных результата. Когда я объединяю @MaterialCompositionEn = ‘, ‘ это работает нормально, когда я пытаюсь объединить @MaterialCompositionEn = тот же запрос, чтобы получить 2-ю строку, у меня есть null!
DECLARE @MaterialCompositionId int = 475;
DECLARE @MaterialCompositionKey nvarchar(50) = '202071512324138';
DECLARE @Records nvarchar(250);
DECLARE @RecordProceed int;
DECLARE @MaterialCompositionEn nvarchar(500);
SET @Records = (SELECT STRING_AGG(Id, ',') FROM MaterialCompositions mc WHERE mc.MaterialCompositionId = @MaterialCompositionId)
WHILE len(@Records) > 0
BEGIN
SET @RecordProceed = CAST(LEFT(@Records,4) AS int)
if @RecordProceed > 0
BEGIN
SET @Records = REPLACE(@Records,substring(@Records, 1, 4),'')
END
if len(@Records) > 4
BEGIN
SET @Records = REPLACE(@Records,substring(@Records, 1, 1),'')
END
if len(@MaterialCompositionEn) > 0
BEGIN
SET @MaterialCompositionEn = ', '
END
PRINT 'MaterialCompositionEn1: ' @MaterialCompositionEn
SET @MaterialCompositionEn =
(SELECT COALESCE (CAST(MaterialProportion AS nvarchar) '% ', '')
(SELECT mp.MaterialPrimaryEn
COALESCE(
(SELECT ' (' ms.MaterialSecondaryEn ')' AS MS1 FROM dbo.MaterialSecondaries AS ms WHERE ms.Id = mc.MaterialSecondaryId)
, '')
FROM dbo.MaterialPrimaries AS mp WHERE mp.Id = mc.MaterialPrimaryId)
FROM MaterialCompositions mc WHERE mc.Id = @RecordProceed
)
PRINT 'MaterialCompositionEn2: ' @MaterialCompositionEn
END
Результат:
MaterialCompositionEn2: 20% Cashmere
MaterialCompositionEn1: 20% Cashmere,
MaterialCompositionEn2: 80% Wool
Теперь, когда я меняю на:
SET @MaterialCompositionEn =
(SELECT COALESCE......
Я ожидаю 20% кашемира, 80% шерсти
, вместо этого мои 3 отпечатка равны НУЛЮ
Я пытался выполнить ПРИВЕДЕНИЕ, но это не помогло.
Есть идеи? Заранее спасибо
Комментарии:
1. ‘Что-то’ NULL = NULL
2. Какую СУБД вы используете? (Этот код зависит от продукта.)
3. Это похоже на SQLServer, подумайте
CONCAT()
о том, чтобы иметь дело с null без такого большого объединения
Ответ №1:
Я предполагаю, что есть гораздо более простой способ сделать то, что вы хотите. Однако, я думаю, проблема в том, что вам нужно инициализировать строку. Итак, в верхней части блока кода поместите:
SET @MaterialCompositionEn = '';
Комментарии:
1. @Philippe . . . Вам нужно будет задать новый вопрос с примерами данных, желаемыми результатами и объяснением логики, которую вы хотите реализовать.
Ответ №2:
SET @MaterialCompositionEn =
SELECT
CONCAT(
mp.MaterialPrimaryEn, ' ', MaterialProportion, '% ', --always show primary
', ' ms.MaterialSecondaryEn CONCAT(100 - MaterialProportion, '%') --sometimes show secondary
)
FROM
MaterialCompositions mc
INNER JOIN dbo.MaterialPrimaries mp ON mp.Id = mc.MaterialPrimaryId
LEFT JOIN dbo.MaterialSecondaries ms ON ms.Id = mc.MaterialSecondaryId
WHERE mc.Id = @RecordProceed
)
Что-то вроде этого может быть аккуратнее.. Обратите внимание, что я не понимаю, откуда берется MaterialProportion (я подозреваю, что MaterialCompositions), так что, возможно, это не решение, просто примечание о том, как вы можете использовать CONCAT / избегать загрузки вложенных выборок. Использование композиций ВНУТРЕННИХ / ВНЕШНИХ соединений и, безусловно, первичный, возможно, вторичный материал. Если вторичный материал равен нулю, то цель состоит в том, чтобы скрыть его с помощью сочетания и сопоставления CONCAT и
CONCAT обрабатывает нули как пустые строки, где as приводит к тому, что все выражение становится нулевым. Это может быть полезно для смешивания и сопоставления, например, в чем-то вроде ', ' ms.MaterialSecondaryEn CONCAT(100 - MaterialProportion, '%')
:
- это
CONCAT(100 - MaterialProportion, '%')
было бы 20% (если бы основной материал составлял 80%), но - в
', ' ms.MaterialSecondaryEn CONCAT(...)
целомNULL
, если MaterialSecondaryEn РАВЕН NULL из левого соединения, не удается сопоставить, поэтому там, где есть только первичный материал, строка, описывающая вторичный, должна полностью исчезнуть как NULL, которую внешний CONCAT обрабатывает как пустую строку