On 1/03/2020 22:57, mailing lists wrote:
Assume I create the following table:
CREATE TABLE Test (ID INTEGER PRIMARY KEY, Value TEXT);
INSERT INTO Test (Value) VALUES('Alpha');
INSERT INTO Test (Value) VALUES('Beta');
INSERT INTO Test (Value) VALUES('Beta');
INSERT INTO Test (Value) VALUES('Alpha');
According to the documentation of group_concat the order is undefined, indeed:
SELECT group_concat(DISTINCT Value) FROM Test ORDER BY Value ASC;
SELECT group_concat(DISTINCT Value) FROM Test ORDER BY Value DESC;
Both queries result in Alpha,Beta.
Changing the queries to
WITH Result(x) AS (SELECT DISTINCT Value FROM Test ORDER BY Value ASC) SELECT
group_concat(x) FROM Result;
WITH Result(x) AS (SELECT DISTINCT Value FROM Test ORDER BY Value DESC) SELECT
group_concat(x) FROM Result;
leads to the results Alpha,Beta, respectively Beta,Alpha.
Is this a coincidence or is this guaranteed to work?
Are there any other solutions / possibilities?
I also sometimes need a deterministic version of group_concat(). For
such cases, I have written the short UDF below (in Python, but I guess
the algorithm can easily be translated in other languages):
JLH
class group_concat2:
# Rewriting of "group_concat" of SQLite to simulate that of MySQL.
# Implements "distinct", "order by", "descending" and "separator".
# Interprets "null" values "intuitively"
#
# Format: group_concat2(value,distinct,sortkey,direction,separator)
# value: char or numeric SQL expression; if numeric,
converted into char;
# the next value to concatenate;
# discarded if None (Python translation of SQL null).
# distinct: numeric or char SQL expression; if char, converted
into integer;
# uniqueness indicator;
# if 1, duplicates ignored; if 0, duplicates allowed.
# sortkey: char or numeric SQL expression (no conversion);
# the order key value for the current "value" instance;
# If None or u'', the current "value" instance is used
instead.
# direction: numeric or char SQL expression; if char, converted
into integer;
# ordering direction (1 = asc; 2 = desc).
# sep: char or numeric SQL expression; if numeric,
converted into char;
# value separator;
# If None, = default u','.
# Example:
# select City,group_concat2(lower(CustID),1,Account,'2','; ') as
Customers
# from CUSTOMER group by City;
def __init__(self):
# Initialize
self.number = 0 # number of values added
self.valList = [] # List of values to concatenate
self.orderby = [] # list of values of the order key
self.distinct = 0 # whether "valList" values must be unique
(0 = no; 1 = yes)
self.direction = 1 # ordering direction (1 = asc; 2 = desc)
self.sep = u',' # separator
def step(self,value,distinct,sortkey,direction,sep):
# Adding a new value to concatenate.
# Each call of this method may specify different values of
# (distinct,sortkey,direction,sep) parameters.
# However, only those specified by the call of the first
"value" instance
# will be considered, the others being ignored.
import numbers
self.number += 1
# Initialize user values of "distinct", "direction" and "sep"
if self.number == 1:
if distinct in [1,u'1']:
self.distinct = 1
if direction in [1,2,u'1',u'2']:
self.direction = int(direction)
if sep is not None:
if isinstance(sep,numbers.Number):
self.sep = unicode(sep)
else:
self.sep = sep
if sortkey is None:
sortkey = value if value is not None else 1
elif sortkey == u'':
sortkey = value if value is not None else 1
if value is not None:
if isinstance(value,numbers.Number):
value = unicode(value)
if self.distinct:
if value not in self.valList:
self.valList.append(value)
self.orderby.append(sortkey)
else:
self.valList.append(value)
self.orderby.append(sortkey)
else:
# value discarded
pass
def finalize(self):
if self.direction == 1:
self.valList = [y for x,y in
sorted(zip(self.orderby,self.valList),reverse=False)]
else:
self.valList = [y for x,y in
sorted(zip(self.orderby,self.valList),reverse=True)]
return self.sep.join(self.valList)
_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users