Элегантный синтаксис для многостолбцового «каскадного» ограничения в SQL? - PullRequest
0 голосов
/ 03 февраля 2009

Я создаю запрос, который будет естественно возвращать результат, который имеет значения для нескольких столбцов, а также некоторые целочисленные столбцы группировки (указывающие, был ли подзаголовок определенного столбца значения, но это само по себе не относится к моему вопросу). Я хочу наложить ограничение на столбцы группировки этого запроса, который принимает только те строки, в которых столбец группировки n не равен нулю, если все столбцы группировки 1 - ( n -1) также ненулевая.

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

where ((grp1 = 0 AND grp2 = 0 AND grp3 = 0 AND ... AND grpn = 0)
    or (grp1 = 1 AND grp2 = 0 AND grp3 = 0 AND ... AND grpn = 0)
    or (grp1 = 1 AND grp2 = 1 AND grp3 = 0 AND ... AND grpn = 0)
    ...
    or (grp1 = 1 AND grp2 = 1 AND grp3 = 1 AND ... AND grpn = 1)

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

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

Ответы [ 2 ]

4 голосов
/ 03 февраля 2009

Вы говорите, что значения являются целыми числами. Могут ли они быть отрицательными? Если нет, вы можете просто использовать набор сравнений:

where (grp1 >= grp2 and grp2 >= grp3 ...)

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

0 голосов
/ 03 февраля 2009

Если (n) исправлено, то ответ Бена кажется лучшим.

Если ваши данные нормализованы и (n) - переменная, я бы предположил, что у вас есть что-то вроде этого ...

data_fk | grp_id | flag

Затем вы хотите найти data_fk, где флаги для различных grp_ids соответствуют установленным вами правилам. На мой взгляд, это правило можно переформулировать как ...

(самое высокое значение group_id, где флаг = 1) должно быть grp_id до (самое низкое значение group_id, где флаг = 0), либо все флаги равны 1, либо все флаги равны 0.

SELECT
    data_fk
FROM
    a_table
GROUP BY
    data_fk
HAVING
    ISNULL(MIN(CASE WHEN flag = 0 THEN grp_id ELSE NULL END), MAX(grp_id) + 1)
    =
    MAX(CASE WHEN flag = 1 THEN grp_id ELSE 0 END) + 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...