首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多对多表上的SQL多连接+逗号分隔

多对多表上的SQL多连接+逗号分隔
EN

Stack Overflow用户
提问于 2009-06-10 05:25:24
回答 2查看 9.8K关注 0票数 0

我有这些表格:

媒体表- id int主键,uri varchar。

media_to_people - media_id整型主键,people_id整型主键

people - id int主键,name varchar,role int -- role指定此人是否为相对于媒体的艺术家、出版商、作家、演员等,范围为(1-10)

这是一个多对多的关系

我想在select中获取一个媒体及其所有相关人员。因此,如果一个媒体有10个人与之关联,那么所有10个人都必须来。

此外,如果给定媒体存在多个具有相同角色的人员,则他们必须以逗号分隔值的形式出现在该角色的列中。

结果标题必须类似于: media.id、media.uri、people.name(演员)、people.name(艺术家)、people.name(出版商)等等。

我使用的是sqlite。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2009-06-10 05:42:02

我同意Alex Martelli的answer的观点,即您应该获取多行数据,并在应用程序中进行一些处理。

如果您尝试仅使用连接来执行此操作,则需要为每个角色类型连接到people表,并且如果每个角色中有多个人,则查询将在这些角色之间使用笛卡尔乘积。

因此,您需要使用GROUP_CONCAT()执行此操作,并在选择列表中为每个角色生成一个标量子查询:

代码语言:javascript
复制
SELECT m.id, m.uri, 
 (SELECT GROUP_CONCAT(name) 
  FROM media_to_people JOIN people ON (people_id = id) 
  WHERE media_id = m.id AND role = 1) AS Actors,
 (SELECT GROUP_CONCAT(name) 
  FROM media_to_people JOIN people ON (people_id = id) 
  WHERE media_id = m.id AND role = 2) AS Artists,
 (SELECT GROUP_CONCAT(name) 
  FROM media_to_people JOIN people ON (people_id = id) 
  WHERE media_id = m.id AND role = 3) AS Publishers
FROM media m;

这真是太难看了!可别在家里尝试这些哟!

请采纳我们的建议,不要尝试仅使用SQL格式化数据透视表。

票数 3
EN

Stack Overflow用户

发布于 2009-06-10 05:37:25

SQLite没有初学者所需要的“轴心”功能,而且“逗号分隔值”部分肯定是一个表示问题,试图推入任何数据库层都是荒谬的(并且可能是不可行的),无论涉及到何种SQL方言--这绝对是您在客户端所做工作的一部分,例如报告工具或编程语言。

使用SQL进行数据访问,并将表示留给其他层。

获取数据的方式是

代码语言:javascript
复制
SELECT media.id, media.uri, people.name, people.role
FROM media
JOIN media_to_people ON (media.id = media_to_people.media_id)
JOIN people ON (media_to_people.people_id = people.id)
WHERE media.id = ?
ORDER BY people.role, people.name

(这个?是在SQLite中指示参数的一种方法,它将绑定到您正在查找的特定媒体id,其方式取决于您的客户端);数据将以几行的形式从DB到达您的客户端代码,您的客户端代码可以很容易地将它们放入您想要的单列形式中。

对于我们来说,很难说出如何编写客户端部分,而不了解您作为客户端所使用的环境或语言。但在Python中,例如:

代码语言:javascript
复制
def showit(dataset):
  by_role = collections.defaultdict(list)
  for mediaid, mediauri, name, role in dataset:
    by_role[role].append(name)
  headers = ['mediaid', 'mediauri']
  result = [mediaid, mediauri]
  for role in sorted(by_role):
    headers.append('people(%s)' % role)
    result.append(','.join(by_role[role]))
  return ' '.join(headers) + '\n' + ' '.join(result)

即使这样也不能很好地匹配您的规范--您要求提供诸如'people(artist)‘之类的标头,同时还指定角色编码为int,并且没有提到从int到字符串'artist’的转换方法,因此显然不可能完全匹配您的规范……但这是我的独创性所能达到的最接近的;-)。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/973790

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档