2013-09-16 6 views
1

Что лучше подходT-SQL необходимой помощи в отношении заявления СЛУЧАЯ в ЗЕЬЕСТЕ

подход-я

SELECT 
SUM(CASE WHEN CODE = 'A' THEN ISNULL(UNIT,0.00)+ISNULL(UNIT_1,0.00) END) AS UNIT_SUM 
FROM tblA 

подход-II

SELECT 
ISNULL(SUM(CASE WHEN CODE = 'A' THEN UNIT+UNIT_1 END),0.00) AS UNIT_SUM 
FROM tblA 

1) моя забота is Do я должен разместить ISNULL внутри оператора CASE или outsite заявление CASE. Это влияет на суммирование единиц ИЛИ оба запроса дают одинаковый результат. И что произойдет, если какой-либо столбец UNIT имеет значение NULL. Это результат NULL из общего числа.

2) делать я должен использовать ELSE в сазе, как указано ниже:

THEN ... ELSE 0,00 END

+0

Размещение 'isnull' снаружи может повлиять лишь на общий результат' суммы() '. –

+0

когда случается, когда вы пытаетесь использовать возможности? –

+0

с некоторым набором результатов, который я попробовал, и оба дают тот же результат. Потому что в будущей записи будет увеличено, что я смотрю на лучший подход. – Sukhjeevan

ответ

1

Ответ на первоначальный вопрос:

Должен ли я размещать ISNULL внутри оператора CASE ...?

Нет, вы этого не сделаете. SUM() игнорирует NULL s. Поэтому наличие значений NULL не повлияет на результат суммирования. Исключение составляет то, что все значения имеют значение NULL или вообще не имеют каких-либо значений. В этом случае вы получите NULL.

Должен ли я использовать инструкцию ELSE в CASE ..?

Нет, вы не по тем же причинам.

... Нужно ли мне использовать ISNULL() вне CASE ..?

Это зависит от того, что вы ожидаете в результирующем в случае, когда все значения NULL s или вы не имеете никаких значений. Если вы хотите иметь 0 или любое другое значение, используйте ISNULL() или COALESCE(). В противном случае нет.

Вот SQLFiddle демо

UPDATE

Учитывая выражение как один в своем измененном вопрос

SUM(CASE WHEN CODE = 'A' THEN UNIT + UNIT_1 END) 

вы скорее всего хотите использовать ISNULL() или COALESCE() вокруг обоих UNIT и UNIT_1, если вы хотите лечить ab отправленное значение одного из этих столбцов как нулевые значения. В том случае, если вы хотите, чтобы получить ноль в результирующем, даже если нет значения, которые соответствуют вашему CASE условию вы все еще нужно использовать ISNULL() или COALESCE() вокруг SUM().

SELECT ISNULL(SUM(CASE WHEN CODE = 'A' 
         THEN ISNULL(UNIT, 0) + ISNULL(UNIT_1, 0) 
        END), 0) AS UNIT_SUM 

или

SELECT COALESCE(SUM(CASE WHEN CODE = 'A' 
         THEN COALESCE(UNIT, 0) + COALESCE(UNIT_1, 0) 
        END), 0) AS UNIT_SUM 

Здесь SQLFiddle демонстрационный

+0

Это самый близкий ответ на вопрос. – danihp

+0

Я сделал немного изменений в заявлении CASE в вопросе. Проверка Plz. – Sukhjeevan

+0

@Sukhi Это очень резкое изменение в вашем вопросе. См. Обновленный ответ. Короче говоря, в этом случае вы, скорее всего, захотите использовать 'ISNULL()' как внутри, так и снаружи 'SUM()' aggregate. – peterm

0

Если вы используете подход-II, вам не нужно ELSE, так что я думаю, в условия более низкого кода.

1

Если вы просто хотите, сумма для тех случаев, когда CODE='A', то я бы написал бы так:

SELECT ISNULL(SUM(UNIT),0.00) AS UNIT_SUM 
FROM tblA 
WHERE CODE = 'A' 

Если вы выбираете другие столбцы тоже, то я бы сделал это так:

SELECT ISNULL(SUM(CASE WHEN CODE = 'A' THEN UNIT ELSE 0.00 END)) AS UNIT_SUM 
FROM tblA 
1

Либо, правильный подход:

SELECT 
ISNULL(SUM(UNIT),0.00) AS UNIT_SUM 
FROM tblA 
WHERE CODE = 'A' --<------------ Index friendly 

Ваш подход плохой, потому что он не поддерживает индекс. Кроме того, с аргументом case вы должны оценить каждую строку.

Если у вас есть несколько столбцов агрегировать вы можете выполнить запрос CTE затем присоединиться результаты:

;with cte_a as (
    SELECT 
    coalesce(SUM(UNIT),0.00) AS UNIT_SUM_A 
    FROM tblA 
    WHERE CODE = 'A' 
), 
cte_b as (
    SELECT 
    coalesce(SUM(UNIT),0.00) AS UNIT_SUM_B 
    FROM tblA 
    WHERE CODE = 'B' 
) 
SELECT UNIT_SUM_A, UNIT_SUM_B 
FROM cte_a cross join cte_b b 

Edited второй запрос по @RomanPekar комментарий.

+1

Второй запрос действительно уродлив, не обобщен вообще и даже может быть улучшен ('cross join' вместо «полного внешнего соединения», переместите «total» в окончательный выбор). Я был бы потрясен, увидев такой запрос в производственном коде. –

+0

@RomanPekar, вы правы. Используется кросс-соединение. – danihp

0

Оба варианта возвращает тот же результат:

1-й заменяет NULLs нулей перед тем суммы и вторые заменяет NULL после СУММ, т.е. нет строки с «A».

Btw, я заменил бы фирменный ISNULL стандартным SQL COALESCE (UNIT, 0.00).

И, конечно, вы могли бы просто заменить его:

CASE WHEN CODE = 'A' THEN UNIT ELSE 0.00 END 
+0

это может привести к различным результатам, если нет строк для суммирования –

+0

Вы правы. Я предположил, что это не полный запрос, будут некоторые другие столбцы или GROUP BY other_column. – dnoeth

2

Вы и другие ответы указывают на то, что лучше поставить фильтр = 'A' в где предложение ускорить запрос, и это правильно делать. Я также хочу отметить, что ваши запросы дают разные результаты в случае, если нет ни одной строки просуммировать:

SELECT 
ISNULL(SUM(CASE WHEN CODE = 'A' THEN UNIT END),0.00) AS UNIT_SUM 
FROM tblA; 
-- output: 0 

SELECT 
SUM(CASE WHEN CODE = 'A' THEN ISNULL(UNIT,0.00) END) AS UNIT_SUM 
FROM tblA; 
-- output: null 

Если вы хотите, чтобы получить сумму всех ваших строк и и поместить эти данные в столбцы, вы можете использовать этот запрос :

select 
    isnull(sum(case when code = 'A' then unit end), 0) as [A], 
    isnull(sum(case when code = 'B' then unit end), 0) as [B] 
from tblA 
-- filter out rows if there's more codes in your table 
where code in ('A', 'B') 

sql fiddle demo

+0

Было бы более элегантно вычислять итоги по одному и, наконец, присоединяться к ним. Ваш запрос вообще не является обобщаемым. Не слишком элегантно, чтобы включить фильтр в предложение, чтобы улучшить производительность. Какой-то код избыточности, который не соответствует простому коду обслуживания. Легко впасть в противоречие, когда утверждение вырастает. – danihp

+0

Я не думаю, что было бы более элегантно вычислять итоги по одному, попробуйте сделать это с помощью 10 элементов, и вы поймете, почему. Что касается моего запроса - он гораздо более обобщаемый, но я думаю, что есть способ его улучшить, попробуем его, когда sqlfiddle будет работать (некоторые проблемы с ним сейчас) –

Смежные вопросы