2013-04-23 2 views
1

Я подумал об использовании инструкции CASE, чтобы очистить некоторые из них, сейчас это работает примерно через 10 секунд. Глядя на конденсацию, а также на избыточные кодовые вызовы. Удивление, если есть лучший способ, чем CASE.Может ли это быть очищено или сгущено любое?

Существует 3 отдельных блока кода. Каждый блок выполняет почти ту же самую вещь, кроме назначения цвета, в зависимости от того, сколько дней он находился в очереди.

Зеленый Все, что менее 1 дня. Желтый ничего более 1 дня, но менее 3 дней. Красный ничего более 3 дней.

select m.number, 'status1', 'Green', datediff(day, (select max(datechanged) from statushistory where accountid = m.number), getdate()) 
from master m with (nolock) 
inner join customer c with (nolock) on m.customer = c.customer 
where m.status = 'status1' 
and datediff(day, (select max(sh.datechanged) from statushistory sh where accountid = m.number), getdate()) <= 1 
and qlevel < 998 
and (m.desk not like 'ATY%') 
and (isnull(m.link,0) = 0 or m.linkdriver = 1) 
and m.desk not in ('param1','param2','param3','param4','param5','param6','param7','param8','param9','param10','param11','param12') 

select m.number, 'status1', 'Yellow', datediff(day, (select max(datechanged) from statushistory where accountid = m.number), getdate()) 
from master m with (nolock) 
inner join customer c with (nolock) on m.customer = c.customer 
where m.status = 'status1' 
and datediff(day, (select max(sh.datechanged) from statushistory sh where accountid = m.number), getdate()) between 1 and 2 
and qlevel < 998 
and (m.desk not like 'ATY%') 
and (isnull(m.link,0) = 0 or m.linkdriver = 1) 
and m.desk not in ('param1','param2','param3','param4','param5','param6','param7','param8','param9','param10','param11','param12') 

select m.number, 'status1', 'Red', datediff(day, (select max(datechanged) from statushistory where accountid = m.number), getdate()) 
from master m with (nolock) 
inner join customer c with (nolock) on m.customer = c.customer 
where m.status = 'status1' 
and datediff(day, (select max(sh.datechanged) from statushistory sh where accountid = m.number), getdate()) >= 3 
and qlevel < 998 
and (m.desk not like 'ATY%') 
and (isnull(m.link,0) = 0 or m.linkdriver = 1) 
and m.desk not in ('param1','param2','param3','param4','param5','param6','param7','param8','param9','param10','param11','param12') 

EDIT # 1

select m.number, 'status1', 
CASE 
    WHEN datediff(day, (select max(sh.datechanged) from statushistory sh where accountid = m.number), getdate()) <= 1 THEN 'Green' 
    WHEN datediff(day, (select max(sh.datechanged) from statushistory sh where accountid = m.number), getdate()) between 1 and 3 THEN 'Yellow' 
    WHEN datediff(day, (select max(sh.datechanged) from statushistory sh where accountid = m.number), getdate()) > 3 THEN 'Red' 
END 
, datediff(day, (select max(datechanged) from statushistory where accountid = m.number), getdate()) 
from master m with (nolock) 
inner join customer c with (nolock) on m.customer = c.customer 
where m.status = 'status1' 
--and datediff(day, (select max(sh.datechanged) from statushistory sh where accountid = m.number), getdate()) <= 1 
and qlevel < 998 
and (m.desk not like 'ATY%') 
and (isnull(m.link,0) = 0 or m.linkdriver = 1) 
and m.desk not in ('param','param','param','param','param','param','param','param','param','param','param','param') 
+1

Я думаю СЛУЧАЙ утверждение путь. – zimdanen

+0

Я бы использовал общее табличное выражение (CTE), см. Http://msdn.microsoft.com/en-us/library/ms175972.aspx – 3dd

+0

@ 3dd Я отредактировал исходное сообщение с моей версией CASE. Вы знаете, как вы можете преобразовать это в CTE? Это результат этого утверждения необходимо будет вставить в таблицу. –

ответ

1
with cte as (
    select 
     m.number, 
     m.status, 
     days = datediff(day, (select max(datechanged) from statushistory where accountid = m.number), getdate()) 
    from 
     master m with (nolock) 
     inner join customer c with (nolock) on m.customer = c.customer 
    where 
     m.status = 'status1' 
     and d between 1 and 2 
     and qlevel < 998 
     and (m.desk not like 'ATY%') 
     and (isnull(m.link,0) = 0 or m.linkdriver = 1) 
     and m.desk not in ('param1','param2','param3','param4','param5','param6','param7','param8','param9','param10','param11','param12') 

), colorThresholds as (
    select color = 'Green', minDays = null, maxDays = 1 union 
    select 'Yellow', 2, 3 union 
    select 'Red', 4, null 
) 

/* now apply the color thresholds */ 
select 
    c.*, 
    ct.color 
from 
    cte c 
    /* outer join in case the thresholds don't cover all ranges */ 
    left outer join colorThresholds ct on 
     (ct.minDays is null or c.days >= ct.minDays) 
     and (ct.maxDays is null or c.days <= ct.maxDays) 
+0

Благодаря dotjoe, я не слишком хорошо знаком с CTE. Мне на самом деле пришлось прокомментировать и от 1 до 2, чтобы он вообще работал. Но даже с тем, что прокомментировал это, кажется, показывают точные результаты, которые я ищу. знаете ли вы, какие преимущества у CTE над вариантом CASE? –

+0

@JamesWilson cte's - это в основном простой (re) -пользовательский подзапрос. Одним из преимуществ является то, что датичная функция находится только в одном месте. Посмотрите, как вам пришлось копировать его для каждого заявления о случаях? что делает его громоздким для поддержания. – dotjoe

+0

@JamesWilson относительно colorThresholds cte, который может быть легко заменен оператором CASE. CTE приятно использовать, когда вы хотите разбить запрос на более мелкие куски. Мне нравится использовать их, когда расчетные/расчетные столбцы понадобятся в других местах, таких как предложение where, объединение или часть других столбцов. Очень стараюсь избегать дублирования кода. – dotjoe

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