“多列”的优雅语法;级联;SQL中的约束?

“多列”的优雅语法;级联;SQL中的约束?,sql,Sql,我正在构造一个查询,它将自然返回一个结果,该结果包含多个列的值,以及一些整数值分组列(指示某个特定值列是否已小计,但其本身与我的问题无关)。我想对这个查询的分组列设置一个约束,如果所有分组列1-(n-1)也非零,则只接受分组列n为非零的行 似乎应该有一种很好的方式用SQL来表达这一点,但到目前为止,我所能想到的只是相当麻烦的方法 where ((grp1 = 0 AND grp2 = 0 AND grp3 = 0 AND ... AND grpn = 0) or (grp1 = 1 AN

我正在构造一个查询,它将自然返回一个结果,该结果包含多个列的值,以及一些整数值分组列(指示某个特定值列是否已小计,但其本身与我的问题无关)。我想对这个查询的分组列设置一个约束,如果所有分组列1-(n-1)也非零,则只接受分组列n为非零的行

似乎应该有一种很好的方式用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的重要部分埋在噪音中


由于这个概念似乎不太常见,我希望有一种更好的方式来表达它,它通常会更简洁,并且希望在服务器上更高效(假设我的原始版本没有那么高效)。

你说这些值是整数。它们可能是负面的吗?如果不是,您可以使用一组比较:

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

编辑:实际上,我还在这里假设非零值必须是1。。。但我想,如果不是这样的话,这个原理仍然可以应用。

你说这些值是整数。它们可能是负面的吗?如果不是,您可以使用一组比较:

where (grp1 >= grp2 and grp2 >= grp3 ...)
编辑:实际上,我还在这里假设非零值必须是1。。。但我想,如果不是这样的话,这个原理仍然可以应用。

如果(n)是固定的,那么本的答案似乎是最好的

如果你的数据是标准化的,(n)是可变的,我假设你有这样的数据

data_fk | grp_id | flag
然后,您需要搜索数据,其中各种grp\U ID的标志符合您设定的规则。这条规则(在我看来)可以重述为

(标志=1的最高组\u id)应该是(标志=0的最低组\u id)之前的grp\u id,或者所有标志都是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
如果(n)是固定的,那么本的答案似乎是最好的

如果你的数据是标准化的,(n)是可变的,我假设你有这样的数据

data_fk | grp_id | flag
然后,您需要搜索数据,其中各种grp\U ID的标志符合您设定的规则。这条规则(在我看来)可以重述为

(标志=1的最高组\u id)应该是(标志=0的最低组\u id)之前的grp\u id,或者所有标志都是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

考虑到您提供的信息,Ben的解决方案似乎是正确的,但是如果您对问题进行了完整的描述(模式、完整SQL等),那么有人可能会从不同的方向来看待问题,从而为您提供更好的解决方案。是(n)变量,还是固定(但较大)模式中的价值?考虑到您提供的信息,Ben的解决方案似乎是正确的,但如果您对问题进行了完整的描述(模式、完整SQL等),则有人可能会从不同的方向来看待问题,从而为您提供更好的解决方案。(n)是变量还是固定(但较大)在你的模式中的价值?这正是我想要的,谢谢。事实证明,是的,列的值总是1和0(我真的应该澄清这一点),这样就可以按书面形式工作。顺便说一下,在非零值可以是任何值的一般情况下,您仍然适用的原则是正确的。这可以用“where((grp2=0或grp1 0)和(grp3=0或grp2 0)和…”来描述,所以很高兴知道如果情况稍有变化,它仍然可以工作。这正是我想要的,谢谢。事实证明,是的,列的值总是1和0(我真的应该澄清这一点)这是书面形式。顺便说一句,在非零值可以是任何值的一般情况下,仍然适用的原则是正确的。这可以通过“where((grp2=0或GRP1 0)和(grp3=0或grp2 0)和…”来涵盖,因此,如果情况稍有变化,它仍然有效。