18

给定一个“事件”表,其中每个事件可能与零个或多个“演讲者”和零个或多个“术语”相关联,这些记录通过连接表与事件相关联,我需要生成一个包含所有事件的表和一列在代表与每个事件关联的“speaker_names”和“term_names”列表的每一行中。

但是,当我运行查询时,speaker_names 和 term_names 值存在重复,因为连接表为每个发言者和事件的术语生成每个关联的行:

1|Soccer|Bobby|Ball
2|Baseball|Bobby - Bobby - Bobby|Ball - Bat - Helmets
3|Football|Bobby - Jane - Bobby - Jane|Ball - Ball - Helmets - Helmets

group_concat 聚合函数能够使用'distinct',它消除了重复,但遗憾的是它不支持我真正需要的自定义分隔符。我留下了这些结果:

1|Soccer|Bobby|Ball
2|Baseball|Bobby|Ball,Bat,Helmets
3|Football|Bobby,Jane|Ball,Helmets

我的问题是:有没有办法可以形成查询或更改数据结构以获得我想要的结果?

请记住,这是我需要的 sqlite3 查询,我无法添加自定义 C 聚合函数,因为这是用于 Android 部署的。

我创建了一个要点,让您可以轻松测试可能的解决方案:https ://gist.github.com/4072840

4

6 回答 6

10

相互独立地查找说话者/术语名称:

SELECT _id,
       name,
       (SELECT GROUP_CONCAT(name, ';')
        FROM events_speakers
        JOIN speakers
          ON events_speakers.speaker_id = speakers._id
        WHERE events_speakers.event_id = events._id
       ) AS speaker_names,
       (SELECT GROUP_CONCAT(name, ';')
        FROM events_terms
        JOIN terms
          ON events_terms.term_id = terms._id
        WHERE events_terms.event_id = events._id
       ) AS term_names
FROM events
于 2012-11-14T18:00:17.827 回答
7

我也遇到了这个问题,但想出了一个我发现更容易理解的方法。由于 SQLite 报告SQLite3::SQLException: DISTINCT aggregates must have exactly one argument,问题似乎与GROUP_CONCAT方法无关,但与 using DISTINCTwithin GROUP_CONCAT...

当您将 DISTINCT '子查询'封装在一个REPLACE实际上什么都不做的方法中时,您可以拥有 nawfal 建议的相对简单性,而没有只能正确连接无逗号字符串的缺点。

SELECT events._id, events.name, 
       (group_concat(replace(distinct speakers.name),'',''), ' - ') AS speaker_names, 
       (group_concat(replace(distinct speakers.name),'',''), ' - ') AS term_names 
FROM events 
LEFT JOIN 
   (SELECT et.event_id, ts.name 
    FROM terms ts 
    JOIN events_terms et ON ts._id = et.term_id
   ) terms ON events._id = terms.event_id 
LEFT JOIN 
   (SELECT sp._id, es.event_id, sp.name 
    FROM speakers sp 
    JOIN events_speakers es ON sp._id = es.speaker_id
   ) speakers ON events._id = speakers.event_id 
GROUP BY events._id;

但实际上我会认为这是一个 SQLite 错误/不一致,或者我错过了什么?

于 2014-05-06T07:57:55.317 回答
5

奇怪的是 SQLite 不支持!

有被否决的风险,只有在它有帮助的情况下:

你可以利用Replace(X, Y, Z)。但是你必须确保你,的列中没有有效值..

SELECT events._id, events.name, 
       REPLACE(group_concat(distinct speakers.name), ',', ' - ') AS speaker_names, 
       REPLACE(group_concat(distinct terms.name), ',', ' - ') AS term_names 
FROM events 
LEFT JOIN 
   (SELECT et.event_id, ts.name 
    FROM terms ts 
    JOIN events_terms et ON ts._id = et.term_id
   ) terms ON events._id = terms.event_id 
LEFT JOIN 
   (SELECT sp._id, es.event_id, sp.name 
    FROM speakers sp 
    JOIN events_speakers es ON sp._id = es.speaker_id
   ) speakers ON events._id = speakers.event_id 
GROUP BY events._id;
于 2012-11-14T16:58:29.833 回答
2

问题只出现在 group_concat(X,Y) 表达式,而不是 group_concat(X) 表达式。

group_concat(distinct X) 效果很好。

所以,如果 ',' 对你有好处,那没有问题,但如果你想要一个 ';' 而不是 ',' (并且您确定原始文本中没有 ',')您可以执行以下操作:

替换(group_concat(不同 X),',',';')

于 2018-04-07T14:21:19.900 回答
1

只是为了提出一个适当的解决方法(murb 的答案奇怪地用括号括起来)。

问题:

group_concat(distinct column_name, 'custom_separator')作为的custom_separator一部分distinct

解决方案:

我们需要一些无操作让 SQLite 知道已经distinct完成(包装 distinct 和它的参数)。No-op 可以用空字符串替换为第二个参数(要替换的文档)。

group_concat(replace(distinct column_name, '', ''), 'custom_separator')

编辑:

刚刚发现它不起作用:-( - 可以调用但distinct不再起作用

于 2014-06-06T13:01:49.847 回答
0

有一种特殊情况在 sqlite 中不起作用:group_concat(DISTINCT X, Y) 而在 SQL 中你可以group_concat(DISTINCT X SEPARATOR Y)在 sqlite 中使用你不能

此示例:Select group_concat(DISTINCT column1, '|') from example_table group by column2; 给出结果:DISTINCT 聚合必须只有一个参数在第 1 行:

解决方案 :

select rtrim(replace(group_concat(DISTINCT column1||'@!'), '@!,', '|'),'@!') from example_table
于 2021-11-07T02:53:13.737 回答