Возврат нескольких строк из условной группы без объединения - PullRequest
0 голосов
/ 09 июня 2018

Я пытаюсь создать запрос, который поддерживает условную группу, в БД SQLite.

Вот что я пробовал до сих пор:

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 голосов
/ 09 июня 2018

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

Если вы можете быть немного гибкими в своих результатах, то вы можете согласовать условия вместе, чтобы получить более сложную группу:

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;

Это те же результаты, но по-разному.

0 голосов
/ 09 июня 2018

Вы не можете использовать 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...