无条件地从条件组返回多行

时间:2018-06-09 03:36:44

标签: sql sqlite

我正在尝试在SQLite DB中构建一个支持条件组的查询。

这是我到目前为止所尝试的内容:

SELECT 
      case 
       when A>1 AND B>1 THEN 1
       when X>1 AND Y>1 THEN 2
       when C>1 AND D>1 THEN 3
      END AS data_grp,
     SUM(col1) AS col1,
     SUM(col2) AS col2
FROM tbl
GROUP BY data_grp;

如果一次只有一个案例,那么这个工作非常好。如果连续多个案例为真,那么它将返回第一个案例,而不是所有令人满意的组。

我在union尝试了这个,效果很好但很慢。有没有其他方法可以使用此条件组快速获取结果。

示例数据&预期结果:

DROP TABLE IF EXISTS  tbl;
CREATE TABLE tbl
(
    A INT,
    B INT,
    C INT,
    D INT,
    X INT,
    Y INT,
    col1 int,
    col2 int

);

INSERT INTO tbl(A,B,C,D,X,Y,col1,col2) values (2,3,0,0,0,0,5,10);
INSERT INTO tbl(A,B,C,D,X,Y,col1,col2) values (0,0,0,0,8,10,3,2);
INSERT INTO tbl(A,B,C,D,X,Y,col1,col2) values (5,4,4,9,0,0,3,2);

    SELECT 
          case 
           when A>1 AND B>1 THEN 1
           when X>1 AND Y>1 THEN 2
           when C>1 AND D>1 THEN 3
          END AS data_grp,
         SUM(col1) AS col1,
         SUM(col2) AS col2
    FROM tbl
    GROUP BY data_grp;

查询输出:

"1" "8" "12"
"2" "3" "2"

预期输出:

"1" "8" "12"
"2" "3" "2"
"3" "3" "2"

2 个答案:

答案 0 :(得分:1)

由于重叠的群组,您无法直接使用GROUP BY。 你可以使用类似的东西,虽然这也可能很慢。

WITH RECURSIVE
  cnt(x) AS (
     SELECT 1
     UNION ALL
     SELECT x+1 FROM cnt
      LIMIT 3
  )
SELECT x as data_grp, sum(col1), sum(col2)
FROM cnt, 
      (SELECT 
          case when A>1 AND B>1 THEN 1  ELSE 0 END as dg1,
          case when X>1 AND Y>1 THEN 2 ELSE 0 END as dg2,
          case when C>1 AND D>1 THEN 3 ELSE 0 END as dg3,
          col1, col2
        FROM tbl) t WHERE x=dg1 or x=dg2 or x=dg3
GROUP BY x

答案 1 :(得分:1)

我对汇总数据持谨慎态度,结果是多行,总数与原始数据不匹配。当然,有时候这是必要的,但这里有两种选择。

如果您的结果略微灵活,那么您可以将条件连在一起以获得更复杂的组:

SELECT ( (CASE WHEN A > 1 AND B > 1 THEN '1' ELSE '' END) ||
         (CASE WHEN X > 1 AND Y > 1 THEN '2' ELSE '' END) ||
         (CASE WHEN C > 1 AND D > 1 THEN '3' ELSE '' END)
       ) AS data_grp,
       SUM(col1) AS col1, SUM(col2) AS col2
FROM tbl
GROUP BY data_grp;

我实际上会把它写成:

SELECT ( (CASE WHEN A > 1 AND B > 1 THEN '1' ELSE '0' END) ||
         (CASE WHEN X > 1 AND Y > 1 THEN '1' ELSE '0' END) ||
         (CASE WHEN C > 1 AND D > 1 THEN '1' ELSE '0' END)
       ) AS data_grp,

所以data_grp得到一个0和1的字符串,表示该组。

这些结果与您的结果相同。如果我正在寻找不同的群体,他们更像我想要的东西 - 我希望看到群体之间的重叠。

或者,我会将值放在不同的列中:

SELECT SUM(CASE WHEN A > 1 AND B > 1 THEN col1 ELSE 0 END) as sum1_1,
       SUM(CASE WHEN X > 1 AND Y > 1 THEN col1 ELSE 0 END) as sum1_2,
       SUM(CASE WHEN C > 1 AND D > 1 THEN col1 ELSE 0 END) as sum1_3,
       SUM(CASE WHEN A > 1 AND B > 1 THEN col2 ELSE 0 END) as sum2_1,
       SUM(CASE WHEN X > 1 AND Y > 1 THEN col2 ELSE 0 END) as sum2_2,
       SUM(CASE WHEN C > 1 AND D > 1 THEN col2 ELSE 0 END) as sum2_3
FROM tbl;

这些结果相同,但转向不同。