2012-06-06 2 views
2

У меня есть функция Excel: = Max (0, min (А1-В1, С1-В1))Самый простой способ реализовать этот SQL-запрос?

и A1, B1, C1 являются столбец Значение в таблице:

Дата, Ключ , Value

предположим теперь дата не имеет значения, и ключ A, B, C для A1, B1, C1

Как реализовать эту функцию первенствовать? Как я изначально это сделал, у меня было два объединения (чтобы получить значения в отдельных столбцах в одной строке), но это казалось излишним, и должен быть более умный способ?

+0

И что случилось с решением двух соединений? – Andomar

+0

Мне нужно будет добавить некоторые критерии отбора (через другое соединение) для каждого из этих объединений, в итоге мне будет около 5 объединений! – mezamorphic

ответ

2

Вы могли бы уменьшить его один присоединиться, так как вам нужно только B для A части:

select case 
     when min(Value - isnull(yt2.Value,0)) > 0 then 0 
     else -min(Value - isnull(yt2.Value,0)) 
     end 
from YourTable yt1 
join YourTable yt2 
on  yt1.Key = 'A' and yt2.key = 'B' 
     or 
     yt1.Key = 'B' and yt2.key = 'C' 
+0

Мне очень жаль, что я только что заметил, что забыл символ минус из C1-B1 – mezamorphic

+0

@Porcupine: отредактирован ответ, но теперь он хуже двух соединений :) – Andomar

1

Ваш вопрос предполагает отдельное значение для каждой строки. Если это так, то это запрос:

select t.* 
     (case when -leastval < 0 then 0 
      else -lesatval 
     end) as TheValue 
    end 
from (select t.*, 
      (case when A1 - B1 < C1 and A1 - B2 < B1 then A1 - B1 
        when C1 < B1 then C1 
        else B1 
       end) as leastval 
     from table t 
    ) t 

Теперь, когда я прочитал вопрос правильно, позвольте мне предположить, что существует одно значение A, B и C в день. Затем вы должны использовать вариант выше, просто сначала деноматизируя данные:

select t.* 
     (case when -leastval < 0 then 0 
      else -leastval 
     end) as TheValue 
    end 
from (select t.*, 
      (case when A - B < C and A - B < B then A - B 
        when C < B then C 
        else B 
       end) as leastval 
     from (select date, 
        min(case when key = 'A' then value end) as A, 
        min(case when key = 'B' then value end) as B, 
        min(case when key = 'C' then value end) as C 
      from table t 
      group by date 
      ) t 
    ) t 

Есть и другие способы сформулировать это. Я старался оставаться достаточно близко к формулировке Excel.

Кстати, некоторые другие базы данных предлагают функции Greatest() и Least(), которые могут создать такую ​​формулу намного проще.

+0

Но таблица не содержит столбцов 'A1',' B1', ' C1'; он имеет столбец «Значение» и «Ключ», содержащий «A, B, C». – Andomar

+0

Приносим извинения за неправильное чтение вопроса. –

+0

Без проблем! +1 для редактирования ответа :) – Andomar

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