Использование предложения ORDER BY внутри функции GROUP_CONCAT в SQLite - PullRequest
5 голосов
/ 23 марта 2012

Я не думаю, что могу использовать предложение ORDER BY внутри функции GROUP_CONCAT.

Кто-нибудь знает хитрый способ выполнить это поведение в SQLite?

Я видел этот вопрос раньше.Но у меня сложный запрос.

Мое утверждение выглядит так:

SELECT
    c.col1, c.col3, m.col3, m.col4,
    count(m.col1), count(re.col2) AS cnt,
    GROUP_CONCAT(p.col1 ORDER BY p.col1) AS "Group1",
    GROUP_CONCAT(p.col2 ORDER BY p.col1) AS "Group2", 
    GROUP_CONCAT(CASE WHEN con.col3 is null THEN p.col1 ELSE con.col3 END),
    con.col4, con.col5, p.col3
FROM t1 re
    INNER JOIN t2  c  ON (re.col1  = c.col1)
    INNER JOIN t3  p  ON (re.col2  = p.col1)
    LEFT JOIN  t4 con ON (con.col1 = p.col2)
    INNER JOIN  t5 m  ON (m.col1   = c.col5) 
GROUP BY re.col1 

Group1 и Group2 поступают из одной таблицы, но из разных столбцов: я хочу сохранитьпорядок Group1 с Group2:

table t3 
+------+------+
| col1 | col2 |
+------+------+
|    1 | A    |
|    2 | B    |
|    3 | C    |
|    4 | D    |
|    5 | E    |
+------+------+

, поэтому, если Group1 выглядит так 2,1,3 Group2 должно выглядеть следующим образом B,A,C

Ответы [ 4 ]

8 голосов
/ 21 мая 2014

SQLite не поддерживает ORDER BY внутри GROUP_CONCAT, но вы можете подделать его:

GROUP_CONCAT(list_order || ':' || value)

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

1 голос
/ 21 февраля 2019

Чтобы избежать какого-либо недетерминизма, вы можете использовать рекурсивный CTE следующим образом:

sqlite> create table t3(pos,col1,col2);
sqlite> insert into t3 values(1,2,'B'),(2,1,'A'),(3,5,'E');
sqlite> select * from t3;
1|2|B
2|1|A
3|5|E
sqlite>
with
  sorted(pos,c1,c2) as (
    select row_number() over (order by t3.pos), -- sorting by first column's value
      t3.col1, t3.col2
      from t3
  ),
  concat(pos,c1,c2) as (
    select sorted.pos,sorted.c1,sorted.c2  -- starting with values for first position
      from sorted
     where sorted.pos=1
     union all
    select sorted.pos,
           concat.c1||','||sorted.c1,  -- adding next value from col1
           concat.c2||','||sorted.c2   -- adding next value from col2
      from concat
      join sorted
        on concat.pos+1 = sorted.pos   -- going through subsequent positions
  )
select c1, c2
  from concat
 order by pos desc
 limit 1;  -- order by desc limit 1 means 'take the row with largest number'

2,1,5|B,A,E

Хотя это решение довольно сложное, оно гарантирует правильную сортировку и может быть легко расширено за счет увеличения числа столбцов. Столбец заказа может содержать пробелы - sorted CTE позаботится о том, чтобы сделать его в правильной целочисленной последовательности.

Обратите внимание, что row_number() over (order by...) может потребоваться прилично свежая версия sqlite, которая поддерживает функции управления окнами.

0 голосов
/ 27 апреля 2017

Как насчет этого?

SELECT 
    col1, col3, col3, col4,
    count(col1), count(re.col2) AS cnt,
    GROUP_CONCAT(p.col1) AS "Group1",
    GROUP_CONCAT(p.col2) AS "Group2", 
    GROUP_CONCAT(CASE WHEN con.col3 is null THEN p.col1 ELSE con.col3 END),
    con.col4, con.col5, p.col3
FROM (
    SELECT 
        *
    FROM t1 re
        INNER JOIN t2  c  ON (re.col1  = c.col1)
        INNER JOIN t3  p  ON (re.col2  = p.col1)
        LEFT JOIN  t4 con ON (con.col1 = p.col2)
        INNER JOIN  t5 m  ON (m.col1   = c.col5) 
    ORDER BY
        p.col1 ASC,
        p.col2 ASC
)
GROUP BY re.col1 

Я не проверял это, но если вы можете поделиться некоторыми данными ...

0 голосов
/ 23 марта 2012

Я попробовал это, и это делает работу

SELECT
    c.col1, c.col3, m.col3, m.col4,
    count(m.col1), count(re.col2) AS cnt,
    GROUP_CONCAT(p.col1 ORDER BY p.col1) AS "Group1",
    GROUP_CONCAT(p.col2 ORDER BY p.col1) AS "Group2", 
    GROUP_CONCAT(CASE WHEN con.col3 is null THEN p.col1 ELSE con.col3 END),
    con.col4, con.col5, p.col3
FROM t1 re
    INNER JOIN t2 c   ON (re.col1  = c.col1)
    INNER JOIN (
        SELECT col1, col2, col3, col4, col5 FROM t3 ORDER BY col1
    ) AS          p   ON (re.col2  = p.col1)
    LEFT JOIN  t4 con ON (con.col1 = p.col2)
    INNER JOIN t5 m   ON (m.col1   = c.col5) 
GROUP BY re.col1 
...