Получите минимальное ненулевое значение в нескольких столбцах

Скажем, у меня есть следующая таблица:

CREATE TABLE numbers
(
  key integer NOT NULL DEFAULT 0,
  number1 integer NOT NULL DEFAULT 0,
  number2 integer NOT NULL DEFAULT 0,
  number3 integer NOT NULL DEFAULT 0,
  number4 integer NOT NULL DEFAULT 0,

  CONSTRAINT pk PRIMARY KEY (key),
  CONSTRAINT nonzero CHECK (key <> 0)
)

Я хочу получить минимальное значение из заданного ключа всех 4 чисел, но игнорируя те, которые равны нулю.

Я начал с чего-то вроде этого, когда решил, что у меня будут проблемы с нулями:

SELECT LEAST(number1, number2, number3, number4) FROM numbers WHERE key = 1

Например, если у меня есть кортеж (1, 5, 0, 3, 2), я хочу вернуть 2, или для (2, 3, 0, 0, 0) я хочу вернуть 3 и так далее.

Можно ли это сделать в одном запросе (или, возможно, вложенном), я действительно не хочу писать процедуру для этого.


person BrunoJ    schedule 09.10.2013    source источник
comment
Я не понимаю, вы сказали, что хотите минимальное ненулевое значение, но затем в ваших двух примерах вы, похоже, противоречили этому.   -  person Eluvatar    schedule 10.10.2013
comment
@Eluvatar: Первое число - это key в его примерах.   -  person Erwin Brandstetter    schedule 10.10.2013


Ответы (2)


Попробуйте функцию NULLIF:

SELECT LEAST(
        nullif( number1, 0 ), 
        nullif( number2, 0 ), 
        nullif( number3, 0 ), 
        nullif( number4, 0 )) 
FROM numbers

Демо -> http://www.sqlfiddle.com/#!12/641fb3/1

person krokodilko    schedule 09.10.2013

LEAST будет игнорировать NULL значения, поэтому должно работать следующее:

select least(n1, n2, n3, n4)
from (
   select case when number1 <= 0 then null else number1 end as n1,
          case when number2 <= 0 then null else number2 end as n2,
          ...
    from numbers
) t

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

person a_horse_with_no_name    schedule 09.10.2013
comment
Да, спасибо, в реальной жизни это свидания, поэтому отрицательных значений нет - person BrunoJ; 10.10.2013
comment
@BrunoJ: Я запутался, 0 - недопустимое значение для даты. - person a_horse_with_no_name; 10.10.2013
comment
это буквально даты с типом даты, где мы используем "0100-01-01" в качестве нулевой даты. - person BrunoJ; 10.10.2013