Выберите, который удовлетворяет как минимум N условиям из M доступных - PullRequest
1 голос
/ 09 июня 2010

возник вопрос.Он установлен в базовых терминах SQL, но его природа чисто математическая (поэтому, возможно, мне стоит посетить http://mathoverflow.com).

У меня есть таблица в некоторой теоретической базе данных с 6 полями, все являются числами.Также у нас есть базовые условия, такие как Field_1> Field_5, Field_4 = 3 и т. Д., Всего 7 условий.Мне нужно написать выбор, который удовлетворяет по крайней мере 4 из них.

Запись looooooooooooooooooooooooooong выберите со многими логическими условиями, такими как (cond_1 И cond_2 И cond_3 и cond_4) ИЛИ (...) не является способом, потому что 4-комбинация из 7 элементов равнадо 140, и никто не хочет писать так много условий.

Итак, как мне написать выбор в упрощенном виде?

Ответы [ 3 ]

6 голосов
/ 09 июня 2010

Один из способов сделать это - посчитать 1 для каждого условия, которому удовлетворяет строка, и сравнить сумму с целевым значением:

SELECT * 
FROM yourtable
WHERE (
          (CASE WHEN condition1 THEN 1 ELSE 0 END) +
          (CASE WHEN condition2 THEN 1 ELSE 0 END) +
          ...
          (CASE WHEN condition7 THEN 1 ELSE 0 END)
      ) >= 4

Обратите внимание, что для этого потребуется оценить все условия для каждой строки, чтобы не было эффекта короткого замыкания, но он прост и, возможно, имеет достаточно хорошую производительность для вас.

Если вы используете MySQL, вы можете написать это гораздо проще, потому что логический результат эквивалентен 0 или 1, поэтому вам не нужны операторы CASE:

WHERE (condition1) + (condition2) + ... + (condition7) >= 4
0 голосов
/ 09 июня 2010

Я бы предложил просто подсчитать, сколько условий выполнено. Конкретный синтаксис будет зависеть от того, какой механизм управления базами данных вы используете, но в MySQL это будет выглядеть примерно так:

SELECT things
FROM places
WHERE IF(cond_1, 1, 0) + IF(cond_2, 1, 0) + IF(cond_3, 1, 0) + IF(cond_4, 1, 0) + IF(cond_5, 1, 0) >= 4;
0 голосов
/ 09 июня 2010

Вы можете просто сложить сумму истинных условий вместе, например,

CASE 
WHEN Field1 > Field5 THEN
    1
ELSE
    0
END
+
CASE
WHEN Field4 = 3 THEN
    1
ELSE
    0
END
+
etc
AS condition_sum

и отфильтровать по условию_суммы> порог.Вы могли бы даже поместить гадость этого выражения суммы случаев в функцию для немного более читаемого кода.

...