#sql #sql-server
Вопрос:
У меня есть список строк продаж, каждая из которых имеет поле валюты. Строка продажи представлена таблицей SALE_LINE, в которой есть поле Валюта для хранения валюты строки продажи.
Я хочу выполнить SQL-запрос, который будет принимать список строк продаж, и если валюта этих строк продаж уникальна для всех, то возьмите эту валюту или установите значение по умолчанию, например доллар.
Например, если у меня есть 3 строки с валютами: EUR, GBP, ZAR, запрос вернет мне ДОЛ. если у меня есть 3 строки с валютами: EUR, EUR, EUR, запрос вернет мне евро.
Мой SQL-запрос выглядит следующим образом:
DECLARE
@salesLineIds VARCHAR(MAX),
@defaultCurrency VARCHAR(10),
@uniqueCurrency VARCHAR(10)
SET @salesLineIds = '1,2,3';
SET defaultCurrency = 'DOL';
DECLARE
@ID_LIST table (Id BIGINT)
INSERT INTO @ID_LIST SELECT TRY_CAST(value AS BIGINT)
FROM STRING_SPLIT(@salesLineIds, ',')
SELECT @uniqueCurrency =(CASE WHEN 1 = (SELECT COUNT(DISTINCT SL.Currency))
THEN
(SELECT DISTINCT SL_CUR.Currency
from SALE_LINE SL_CUR
where SL_CUR.Id in (SELECT * FROM @ID_LIST)
)
ELSE
@defaultCurrency
END)
FROM SALE_LINE SL
WHERE SL.Id IN (SELECT * FROM @ID_LIST)
Вышесказанное работает, но это может быть не очень хорошая производительность. Есть ли какой-либо способ улучшить производительность приведенного выше запроса?
Приведенный ниже запрос не дает хорошей валюты:
SELECT @uniqueCurrency =(CASE WHEN 1 = (SELECT COUNT(DISTINCT SL.Currency))
THEN
(SELECT DISTINCT SL.Currency
)
ELSE
@defaultCurrency
END)
FROM SALE_LINE SL
WHERE SL.Id IN (SELECT * FROM @ID_LIST)
group by SL.Currency
Любая помощь в том, как я могу улучшить работу с SQL, будет оценена по достоинству. Спасибо
Комментарии:
1. «но это может быть не очень хорошая производительность» — это проблема с измеряемой производительностью?
2. @MitchWheat : Я также хочу знать, есть ли лучший способ сделать это.
3. лучше? в каком смысле?
4. Доллар США-это валюта. AUD-это валюта, CAD-это валюта. Но ДОЛ — это не валюта.
Ответ №1:
Вам нужно сгруппировать весь набор, а затем просто проверить наличие различных Currency
значений. Если есть только один, то вы можете просто использовать любую агрегацию , например MIN
, чтобы получить ее.
DECLARE
@salesLineIds VARCHAR(MAX),
@defaultCurrency VARCHAR(10),
@uniqueCurrency VARCHAR(10);
SET @salesLineIds = '1,2,3';
SET defaultCurrency = 'DOL';
DECLARE
@ID_LIST table (Id BIGINT);
INSERT INTO @ID_LIST SELECT TRY_CAST(value AS BIGINT)
FROM STRING_SPLIT(@salesLineIds, ',');
SELECT @uniqueCurrency =
CASE WHEN COUNT(DISTINCT SL.Currency) = 1
THEN MIN(SL.Currency)
ELSE @defaultCurrency
END
FROM SALE_LINE SL
WHERE SL.Id IN (SELECT * FROM @ID_LIST);
Я предлагаю
CHAR(3)
в качестве подходящего типа данных для валюты
Ответ №2:
Если не считать нулей.
SELECT
CASE WHEN min(SL.Currency) = max(SL.Currency)
THEN min(SL.Currency)
ELSE @defaultCurrency
END
FROM SALE_LINE SL
WHERE SL.Id IN (SELECT * FROM @ID_LIST);
Комментарии:
1. Я не уверен, что вышесказанное будет работать с 3 строками с валютами: EUR, GBP, EUR
2. По сути, это то же самое, что и другой ответ. В вашем примере min не равен max, который проходит по мере необходимости.