如何在普通的sql中模拟group_concat

时间:2012-02-27 19:12:56

标签: sql hxtt

我正在使用hxtt sql驱动程序来获取csv文件。它只支持普通的sql。有没有办法使用普通的sql语句来模拟组连接?

1 个答案:

答案 0 :(得分:3)

多么平淡?如果你可以使用触发器,那么你可以相当简单地完成它。我之前在SQLite3中使用过这个技巧,当我需要一个group_concat()时,它允许我指定连接值的顺序(SQLite3没有提供这样做的方法)。

所以我们假设我们有一个这样的表:

CREATE TABLE t(v TEXT NOT NULL, num INTEGER NOT NULL UNIQUE);

并且你希望将由num排序的v的值与一些分隔符连接起来,假设是逗号。

CREATE TEMP TABLE c(v TEXT);
CREATE TEMP TABLE j(v TEXT);

CREATE TEMP TRIGGER j_ins BEFORE INSERT ON j
FOR EACH ROW
BEGIN
    UPDATE c SET v = v || ',' || NEW.v;
    INSERT INTO c (v) SELECT NEW.v WHERE NOT EXISTS (SELECT * FROM c);
    SELECT RAISE(IGNORE);
END;

现在我们可以:

INSERT INTO j (c) SELECT v FROM t ORDER BY num;
SELECT v FROM c; -- this should output the concatenation of the values of v in t
DELETE FROM c;

最后,这是一个sqlite3会话,显示这有效:

SQLite version 3.7.4
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> CREATE TABLE t(v TEXT NOT NULL, num INTEGER NOT NULL UNIQUE);
sqlite> CREATE TEMP TABLE c(v TEXT);
sqlite> CREATE TEMP TABLE j(v TEXT);
sqlite> CREATE TEMP TRIGGER j_ins BEFORE INSERT ON j
   ...> FOR EACH ROW
   ...> BEGIN
   ...>     UPDATE c SET v = v || ',' || NEW.v;
   ...>     INSERT INTO c (v) SELECT NEW.v WHERE NOT EXISTS (SELECT * FROM c);
   ...>     SELECT RAISE(IGNORE);
   ...> END;
sqlite> insert into t (v, num) values (1, 0);
sqlite> insert into t (v, num) values (31, 1);
sqlite> insert into t (v, num) values (52, 2);
sqlite> insert into t (v, num) values (0, 3);
sqlite> SELECT v FROM c;
sqlite> INSERT INTO j (v) SELECT v FROM t ORDER BY num;
sqlite> SELECT v FROM c;
1,31,52,0
sqlite> SELECT v FROM j;
sqlite> DELETE FROM c;
sqlite> 

现在,这不是纯SQL,因为它依赖于触发器。在递归触发器和在SQL中执行条件的所有方法之间,您有一个图灵完备系统。但是如果你没有触发器或任何程序扩展,那么没有生成器表......那就不那么多了。

我对hxtt一无所知,所以也许这对你没有帮助。但SQLite3可以处理CSV,所以也许SQLite3可以帮助你......