Используя преимущества сравнения объектов bool
и tuple
, это легко записать как
(current_section=="PM",current_hour%12,current_minute)<(due_section=="PM",due_hour%12,due_minute)
. Конечно, канонизация числом минут с полуночи является более общей: 111]
... который можно сделать функцией, которая будет применяться любое количество раз.
Нет необходимости для переопределения функций PostgreSQL уже предоставляет: bool_and () выполнит работу:
select bool_and(someBool)
from myTable
where someKey = $1
group by someKey;
(извините, не могу сейчас это проверить)
Подобный предыдущему, но в одном запросе, это добьется цели, однако, это не чистый ни легко понятный код:
SELECT someKey,
CASE WHEN sum(CASE WHEN someBool THEN 1 ELSE 0 END) = count(*)
THEN true
ELSE false END as boolResult
FROM table
GROUP BY someKey
Это получит все ответы сразу, если Вы только захотите один ключ, просто добавляют оператор Where
Я просто установил PostgreSQL впервые на этой неделе, таким образом, необходимо будет очистить синтаксис, но общее представление здесь должно работать:
return_value = NULL
IF EXISTS
(
SELECT
*
FROM
My_Table
WHERE
some_key = $1
)
BEGIN
IF EXISTS
(
SELECT
*
FROM
My_Table
WHERE
some_key = $1 AND
some_bool = 'f'
)
SELECT return_value = 'f'
ELSE
SELECT return_value = 't'
END
Идея состоит в том, что только необходимо посмотреть на одну строку, чтобы видеть, существует ли кто-либо и если по крайней мере одна строка существует, затем только необходимо посмотреть, пока Вы не находите, что ложное значение решает, что окончательное значение является ложью (или Вы добираетесь в конец, и это верно). Предположение, что у Вас есть индекс на some_key, производительность, должно быть хорошим, я думал бы.
Возможно, считайте 'все' объекты с somekey=somevalue и используйте его в булевом сравнении с количеством всех 'Истинных' происшествий для somekey?
Некоторые не протестировали pseudo-sql для показа то, что я имею в виду...
select foo1.count_key_items = foo2.count_key_true_items
from
(select count(someBool) as count_all_items from myTable where someKey = '1') as foo1,
(select count(someBool) as count_key_true_items from myTable where someKey = '1' and someBool) as foo2
CREATE FUNCTION do_and(int4)
RETURNS boolean AS
$BODY$
SELECT
MAX(bar)::bool
FROM (
SELECT
someKey,
MIN(someBool::int) AS bar
FROM
myTable
WHERE
someKey=$1
GROUP BY
someKey
UNION
SELECT
$1,
NULL
) AS foo;
$BODY$
LANGUAGE 'sql' STABLE;
В случае, если Вам не нужно Нулевое значение (когда нет никаких строк), просто используйте запрос ниже:
SELECT
someKey,
MIN(someBool::int)::bool AS bar
FROM
myTable
WHERE
someKey=$1
GROUP BY
someKey
(Очень второстепенный аспект: я думаю, что ваша функция должна быть объявлена STABLE, а не VOLATILE, поскольку она просто использует данные из базы данных для определения своего результата.)
Как кто-то упомянул, Вы можете остановить сканирование, как только вы встретите «ложное» значение. Если это распространенный случай, вы можете использовать курсор, чтобы фактически вызвать «быстрое завершение»:
CREATE FUNCTION do_and(key int) RETURNS boolean
STABLE LANGUAGE 'plpgsql' AS $$
DECLARE
v_selector CURSOR(cv_key int) FOR
SELECT someBool FROM myTable WHERE someKey = cv_key;
v_result boolean;
v_next boolean;
BEGIN
OPEN v_selector(key);
LOOP
FETCH v_selector INTO v_next;
IF not FOUND THEN
EXIT;
END IF;
IF v_next = false THEN
v_result := false;
EXIT;
END IF;
v_result := true;
END LOOP;
CLOSE v_selector;
RETURN v_result;
END
$$;
Этот подход также означает, что вы выполняете только один просмотр myTable. Имейте в виду, я подозреваю, что вам нужны нагрузки и ряды строк, чтобы разница была заметной.
SELECT DISTINCT ON (someKey) someKey, someBool
FROM myTable m
ORDER BY
someKey, someBool NULLS FIRST
При этом будет выбрано первое упорядоченное логическое значение для каждого someKey
.
Если имеется одно значение FALSE
или NULL
, он будет возвращен первым, что означает, что выполнение И
завершилось ошибкой.
Если первое логическое значение - ИСТИНА
, то все остальные логические значения также будут ИСТИНА
для этого ключа.
В отличие от агрегата, здесь будет использоваться индекс на (someKey, someBool)
.
Чтобы вернуть OR
, просто измените порядок:
SELECT DISTINCT ON (someKey) someKey, someBool
FROM myTable m
ORDER BY
someKey, someBool DESC NULLS FIRST