Значение обновления SQL Server в столбце с ГРУППОЙ ПО и условием суммы и определенным значением

#sql #sql-server

Вопрос:

Назначение Тип Сумма Комментарии
1018140292 SA 14.51 Разница в Валюте
1018140292 RV -16.56 Разница в Валюте

Сценарий : Мне нужно обновить столбец комментариев в базе данных, если сумма значений столбца «Сумма» для нескольких позиций с одним и тем же назначением находится в диапазоне (-10) — ( 10). Данные будут сгруппированы по столбцу Назначения. Однако у меня возникла проблема, когда мы можем подвести итоги только в том случае, если задание содержит тип столбца с «SA» И «RV», когда мы группируемся.

Ниже приведен мой запрос, который я попытался выполнить.

 update tbl_NO300_Details
set Comments='Currency Variance'
where Assignment in(
select Assignment 
from tbl_NO300_Details Intbl where Type in ('RV', 'SA')
group by Intbl.Waybill,right(Shipment_Date,7 )
having count(*)>1 and sum(cast(Amount as float))>-10 and sum(cast(LC_Amount as float))<10)
 

Проблема :

Когда я сталкиваюсь с таким случаем, когда есть несколько строк только с SA, он также обновит столбец комментариев с «Изменением валюты», что неверно. В этом случае нам нужны «RV» и «SA».

Назначение Тип Сумма Комментарии
1018140292 SA 5.00 Разница в Валюте
1018140292 SA 4.00 Разница в Валюте

Правильный вывод должен быть, он не будет обновлять столбец комментариев (должен быть пустым). :

Назначение Тип Сумма Комментарии
1018140292 SA 5.00
1018140292 SA 4.00

Буду признателен, если вы поможете решить мою проблему.

Спасибо.

Комментарии:

1. Примечание: преобразование значения, которое явно предназначено для представления денежной стоимости, в a float -очень плохая идея. float является (сюрприз!) значением с плавающей запятой и не является точным. Вы можете легко ввести ошибки, используя такой тип данных для денежных значений.

2.Кроме того, and Type in ('RV', 'SA') должно быть в WHERE не то HAVING .

3. @Larnu , я отредактировал свой запрос с помощью ввода » где » («RV», «SA») в правильном месте.

Ответ №1:

Для выполнения вычислений можно использовать оконные условные агрегаты.

Сделайте это внутри CTE или производной таблицы и обновите ее непосредственно через нее.

 UPDATE t
SET Comments = 'Currency Variance'
FROM (
    SELECT *,
        countRV = COUNT(CASE WHEN Type = 'RV' THEN 1 END)
            OVER (PARTITION BY Intbl.Waybill, RIGHT(Shipment_Date, 7)),
        countSA = COUNT(CASE WHEN Type = 'SA' THEN 1 END)
            OVER (PARTITION BY Intbl.Waybill, RIGHT(Shipment_Date, 7)),
        sm = SUM(CASE WHEN Type IN ('RV', 'SA') THEN Amount END)
            OVER (PARTITION BY Intbl.Waybill, RIGHT(Shipment_Date, 7))
    FROM tbl_NO300_Details Intbl
) t
WHERE countRV > 0 AND countSA > 0
  AND sm > -10 AND sm < 10
 

Примечания:

  • Не конвертируйте в float, если в этом нет необходимости. Если вам нужно преобразовать строки в числа, преобразуйте decimal их в, если сможете
  • Непонятно RIGHT(Shipment_Date, 7) , для чего это нужно. Если вы пытаетесь вычеркнуть время из datetime значений, это не лучший способ сделать это

Комментарии:

1. Привет @Charlieface, спасибо за вашу помощь, однако, я попробовал запрос, похоже, он возвращает неверный вывод для случая, когда оба типа «SA». Вы можете обратиться к этой скрипке. Ссылка

2. Я отредактировал его очень скоро после того, как опубликовал, это должно было сработать, если бы не пара синтаксических ошибок, которые теперь исправлены. Видишь dbfiddle.uk/…