首页 > 解决方案 > 我正在尝试在取决于列的列中求和,然后再成为 1

问题描述

我有 12 列有“1”或“0”。我想对所有这些的第一列进行总和。然后,如果第一列都是'1',那么我想得到第2列中所有'1'的总和。然后,如果第1列和第2列都是'1',那么我想得到总和第 3 列中的所有“1”。依此类推....我正在尝试使用以下情况进行操作。但是,它工作正常,直到第 3 列,在第 4 列之后我只得到 NULL。

SUM (CASE WHEN MAX(B.PREVIOUS_1) = 1  THEN  1  END ) TOTAL_MONTH_1,
SUM (CASE WHEN MAX(B.PREVIOUS_1) = 1 AND  MAX(B.PREVIOUS_2) = 1  THEN 1  END )TOTAL_MONTH_2,
    SUM (CASE WHEN MAX(B.PREVIOUS_1) = 1 AND  MAX(B.PREVIOUS_2) = 1 AND  MAX(B.PREVIOUS_3) = 1 THEN  1  END ) TOTAL_MONTH_3,
    SUM (CASE WHEN MAX(B.PREVIOUS_1) = 1 AND  MAX(B.PREVIOUS_2) = 1 AND  MAX(B.PREVIOUS_3) = 1 AND  MAX(B.PREVIOUS_4) = 1 THEN  1  END ) TOTAL_MONTH_4,
    SUM (CASE WHEN MAX(B.PREVIOUS_1) = 1 AND  MAX(B.PREVIOUS_2) = 1 AND  MAX(B.PREVIOUS_3) = 1 AND  MAX(B.PREVIOUS_4) = 1 AND  MAX(B.PREVIOUS_5) = 1 THEN  1  END ) TOTAL_MONTH_5

我希望得到

column 1   column 2   column 3....... 
1            1        0
0            1        1
1            0        0

结果:

2            1        0

标签: sqloracle

解决方案


好吧,我不得不承认,这个问题让我很感兴趣!我之所以回答是因为我讨厌 SQL 查询的文本长度基于列数的平方的想法。因为,老实说,如果你有 12 列 (12 * 12 / 2),你将有 72 个 case 语句。这种代码维护起来很糟糕,修改起来也很糟糕。

因此,我将像解决数学难题一样解决这个问题。假设只有两列:a 和 b。如果a=0,则答案为0;如果 a=1,如果 b=0,答案是 1,如果 b=1,答案是 2。嗯,这很简单:答案是:a*(a+b)。如果 a=0,则将某个数字乘以 0,即为零。

或者我们甚至可以更花哨 - 我们可以说它是 * (1+b) - 任何一种方式都有效,这样,我们在图片中只有一个“a”。

Answer(a,b) = a*(1+b)

好的,但是第三列呢?

现在我们有 a、b 和 c。如果 a = 0,我们的答案仍然为零。但是如果 a = 1,我们的答案应该是 1 + Answer(b,c)。

Answer(a,b,c) = a*(1+Answer(b,c))
Answer(a,b,c) = a*(1+b*(1+c)

那有意义吗?现在我们知道了,模式非常明显:

Answer(a,b,c,d,....) = a*(1+b*(1+c*(1+d* ...

好的 - 那么我们如何看待长度?每个术语 - 每列 - 只使用一次。如果您有 12 列,那么您将只有 12 个术语!不是72!(另外,很容易扩展它以包含另外几列。)

更好的是,此时很容易获得每个“列”的总和。毕竟,您的数据看起来像:

ColA,ColB,ColC,ColD,KevinsAnswer
0    1    0    0    0
1    1    0    1    2
1    1    1    1    4
0    0    1    0    0
1    0    0    0    1
1    1    1    0    3

如果您想知道有多少行至少有两个 1?获取 KevinsAnswer >= 2 的 sum()。

所以我的最终答案是这样的(如果这里有任何非 oracle 命令,我深表歉意;我的专长是 MS SQL)

select StraightMonths,Count(*) from
(
    select B.PREVIOUS_1 *
        (1 + B.PREVIOUS_2 *
        (1 + B.PREVIOUS_3 *
        (1 + B.PREVIOUS_4 *
        (1 + B.PREVIOUS_5 *
        (1 + B.PREVIOUS_6 *
        (1 + B.PREVIOUS_7 *
        (1 + B.PREVIOUS_8 *
        (1 + B.PREVIOUS_9 *
        (1 + B.PREVIOUS_10 *
        (1 + B.PREVIOUS_11 *
        (1 + B.PREVIOUS_12 ))))))))))) as StraightMonths
    ) as straightMonthsSubquery
) group by StraightMonths

...然后将用作子查询来获取您感兴趣的特定月份;请记住,如果您想要month=2,则必须 SUM() StraightMonths >= 2 的值(2 条目中的值恰好是两个月的值。)或者甚至只是从查询中输入该数据进入一个临时/变量表(它只有 12 行,一列。)


推荐阅读