Sql Server - выбор логических результатов в запросе - PullRequest
4 голосов
/ 28 сентября 2011

Предположим, у меня есть таблица: ACCOUNT
В ней есть столбцы: ID, NAME, BALANCE

Я хочу определить, соответствует ли СУММА балансов людей, имеющих балансболее 2000 долларов - больше, чем 50000 долларов.Это значит, что я хочу выбрать логическое значение.Поскольку я не хочу получать конкретную сумму, мне нужен только результат сравнения.Я хочу иметь возможность написать что-то вроде:

SELECT SUM(BALANCE) > 50000 
  FROM ACCOUNT
 WHERE BALANCE > 2000

Sql Server говорит, что это синтаксическая ошибка.Поэтому я должен сделать:

SELECT SUM(BALANCE)  
  FROM ACCOUNT
 WHERE BALANCE > 2000

Затем сравнить результат с 50000. Но брать сумму всех предметов после достижения 50000 является излишним, поскольку я сравниваю только с 50000.

Так как мне написать этот запрос таким образом, чтобы он останавливался после достижения значения сравнения и давал мне логический результат?

Ответы [ 6 ]

2 голосов
/ 28 сентября 2011

Нет.

Как SQL Server узнает, что у вас есть только положительные значения?Если у вас есть 10 значений, а восьмое дает вам 50,000, но 9 и 10 оба -10,000, разве это не проблема?

1 голос
/ 28 сентября 2011

Вы не можете остановить запрос, если не создадите процедуру с курсором, который прекратит выборку после достижения 50000 (не знаю, стоит ли это, но это единственный способ, возможно, у вас есть миллионы строк):

DECLARE @bal int
DECLARE @bal_tot int
DECLARE cur CURSOR FOR 
SELECT sum(balance)
FROM account
WHERE balance > 2000
ORDER BY balance DESC;

OPEN cur;

FETCH NEXT FROM cur
INTO @bal
WHILE @@FETCH_STATUS = 0 AND @bal_tot < 50000
BEGIN
@bal_tot = @bal_tot + @bal
END
CLOSE cur;

if @bal_tot > 50000 etc...
1 голос
/ 28 сентября 2011

На самом деле нет чистого способа сделать это и заставить SQL Server замкнуть сканирование, как только будет достигнута общая сумма.

Вместо этого вы можете использовать рекурсивный CTE для сложения весов.Условие выхода для этого может быть, когда итоговая сумма баланса превышает 50 000.В зависимости от количества элементов таблицы и индексов это может быть более или менее эффективным.

У вас также может быть собственный агрегат CLR, который прекращает обработку, выдавая ошибку, если достигнут 50 000, но довольно ужасное решение!

1 голос
/ 28 сентября 2011

Посмотрите на ключевое слово HAVING.

SELECT sum(balance)
FROM account
WHERE balance > 2000
HAVING sum(balance) > 50000

Редактировать: Это вероятно не ярлык, как первоначальный вопрос. Это может , если механизм запросов SQL Server понял, что предложения where / has могут быть сокращены (как сказал Мартин Смит в комментарии). Я думаю, что написание собственного ярлыка будет слишком сложным, и если вы столкнетесь с проблемами производительности, вероятно, будут более подходящие подходы.

Если вам нужен истинный / ложный ответ с помощью запроса, то ответ Джима Дагга мне подходит.

0 голосов
/ 28 сентября 2011
SELECT CASE WHEN  TotalAmtCurrent > 50000  THEN 1  ELSE 0  END 
FROM
    (SELECT SUM(AmtCurrent)  as TotalAmtCurrent    
    FROM [SisMaster].[dbo].[Loan]     
    WHERE AmtCurrent > 2000) a
0 голосов
/ 28 сентября 2011

Я бы не стал пытаться написать сложную процедуру для короткого замыкания запроса. - это слишком сложная проблема. Честно говоря, просто вывести сумму и сделать сравнение, как вы делаете сейчас, является самым простым методом. Если вы хотите выбрать результат сравнения для использования в другой обработке SQL, вы можете попробовать это:

SELECT CASE WHEN 
    (SELECT SUM(AmtCurrent)
     FROM [SisMaster].[dbo].[Loan]
     WHERE AmtCurrent > 2000) > 50000 
THEN 1 
ELSE 0 
END
...