在 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
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
【问题讨论】:
您在答案中写道,查询可以满足您的需求。那么问题是什么? @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_CONCAT
s 中删除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 相同?
group_concat 以及如何在 sqlite 中使用行号