在 SQLite 的 GROUP_CONCAT 函数中使用 ORDER BY 子句

Posted

技术标签:

【中文标题】在 SQLite 的 GROUP_CONCAT 函数中使用 ORDER BY 子句【英文标题】:Using ORDER BY clause inside GROUP_CONCAT function in SQLite 【发布时间】:2012-04-07 15:39:32 【问题描述】:

我认为我不能在GROUP_CONCAT 函数中使用ORDER BY 子句。

有没有人知道在SQLite 中实现这种行为的棘手方法?

我以前看过这个question。但我有一个复杂的查询。

我的陈述如下:

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 

Group1Group2 来自同一个表但不同的列:我想保留 Group1Group2 的顺序:

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

所以如果Group1 出现这样2,1,3 Group2 应该出现这样B,A,C

【问题讨论】:

您在答案中写道,查询可以满足您的需求。那么问题是什么? @newtover 他使用的语法被mysql而不是sqlite支持。 Sqlite group_concat ordering的可能重复 【参考方案1】:

为避免任何不确定性,您可以像这样使用递归 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。

【讨论】:

【参考方案2】:

这样的事情呢?

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 

我还没有测试过,但如果你可以分享一些数据......

【讨论】:

【参考方案3】:

我已经尝试过了,它成功了

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 

【讨论】:

SQLite 真的支持GROUP_CONCAT(column ORDER BY some_column) 语法吗?对我来说,它在ORDER (SQLite 3.4.7) 失败 这在 sqlite 中不起作用。就像上面说的 zapl 一样,它在 ORDER 上失败了 @confucius 我认为这里的关键是您按照命令重写了t3,但是忘记从GROUP_CONCATs 中删除ORDER BY p.col1【参考方案4】:

SQLite 不支持 ORDER BY 内的 GROUP_CONCAT,但您实际上可以伪造它:

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

然后您需要将结果拆分为代码,以便取回您的排序和值。

【讨论】:

你能详细说明一下吗?我不明白你的回答。 @nowox 您不能使用 SQLite 在 GROUP_CONCAT 中直接排序,因此此命令会将 list_order 与分隔符(这里我使用“:”)和值连接起来。然后在解析结果时(对我来说,我使用的是 android),将数据保存在列表中并根据 list_order 重新排序。

以上是关于在 SQLite 的 GROUP_CONCAT 函数中使用 ORDER BY 子句的主要内容,如果未能解决你的问题,请参考以下文章

在 SQLite 的 GROUP_CONCAT 函数中使用 ORDER BY 子句

Sqlite group_concat 排序

在 SQLite 中,多个列的排序方式是不是与 group_concat 相同?

group_concat 以及如何在 sqlite 中使用行号

SQLite - 是不是可以在同一个查询中使用 group_concat 函数但 'GROUP BY' 不同的标准?

获取 SQLite 中 GROUP_CONCAT 的所有 id