mysql 5中的多列子选择(5.1.42)

时间:2010-03-15 20:42:21

标签: sql mysql subquery

这个似乎是一个简单的问题,但我不能让它在一个单独的工作 选择或嵌套选择。检索作者和(如果有的话)顾问 纸(文章)分成一行。

我为了解释这个问题,这里有两个数据表(伪)

papers (id, title, c_year)
persons (id, firstname, lastname)

加上一个带有一个额外属性(伪)的链接表:

paper_person_roles(
  paper_id
  person_id
  act_role ENUM ('AUTHOR', 'ADVISER')
)

这基本上是一份书面文件清单(表格:论文)和清单 工作人员和/或学生(表:人)

我有(1,N)作者的文章 一篇文章可能有(0,N)顾问 一个人可以是“AUTHOR”或“ADVISER”角色(但不能同时)。

应用程序最终会输出包含以下内容的表行 输入:

TH: || Paper_ID  |  Author(s)          |   Title                 |   Adviser(s)  |
TD: ||   21334   |John Doe, Jeff Tucker|Why the moon looks yellow|Brown, Rayleigh|
...

我的第一种方法是: 选择/提取完整的文章列表到应用程序中,例如

SELECT 
   q.id, q.title
FROM 
   papers AS q
ORDER BY 
   q.c_year
并将查询结果保存到数组中(在应用程序中)。在这之后 步骤,循环返回信息的数组并检索作者和 顾问(如果有的话),通过准备好的声明(?是论文的ID)来自链接表 像:
APPLICATION_LOOP(paper_ids in array)
  SELECT 
      p.lastname, p.firstname, r.act_role 
  FROM 
      persons AS p, paper_person_roles AS r
   WHERE 
      p.id=r.person_id AND r.paper_id = ?
   # The application does further processing from here (pseudo):
   foreach record from resulting records
     if  record.act_role eq 'AUTHOR' then join to author_column
     if  record.act_role eq 'ADVISER' then join to avdiser_column
   end
   print id, author_column, title, adviser_column
APPLICATION_LOOP
这到目前为止工作并提供所需的输出。它会成功吗? 是否将计算重新放入数据库?

我对非平凡的SQL并不是很精通,也找不到 单个(组合或嵌套)选择调用的解决方案。一世 试过了......喜欢

SELECT
    q.title 
    (CONCAT_WS(' ',
     (SELECT p.firstname, p.lastname AS aunames
      FROM persons AS p, paper_person_roles AS r
      WHERE q.id=r.paper_id AND r.act_role='AUTHOR')
     )
    ) AS aulist
FROM 
    papers AS q, persons AS p, paper_person_roles AS r
在几个变化中,但没有运气...

也许有机会?

提前致谢

r.b。

2 个答案:

答案 0 :(得分:2)

根据我的经验,SQL数据库并不擅长将表格数据聚合成单行精简数据。基本上我认为你使用的方法很好,但跳到我身边的另一个选择就是加入人员表,这样你就可以为每个对某一特定纸张有作用的人提供一行。

类似的东西:

    SELECT q.id, q.title, p.firstName, p.lastName, r.act_role FROM papers q, persons p, 
        paper_person_roles r where r.paper_id = q.id and r.person_id = p.id

对于上面显示的给定示例,您将获得如下数据:

21334   |Why the moon looks yellow|John Doe   |AUTHOR
21334   |Why the moon looks yellow|Jeff Tucker|AUTHOR
21334   |Why the moon looks yellow|Brown      |ADVISER
21334   |Why the moon looks yellow|Rayleigh   |ADVISER

并且很容易解析您正在寻找的最终结果。

有了这些事情,所有这些都是为了权衡:        - 你是否花了太多时间一遍又一遍地回到数据库?        - 是否有太多数据无法一次加入?        - 您的“优化”最终会使您的代码难以阅读吗?

坦率地说,如果您的代码按照您想要的方式运行并且尚未达到性能障碍,那么请保持原样并在您开始看到性能下降的那一天回到此决策,因为您的数据集会缩放起来。

答案 1 :(得分:2)

以下查询适用于我的测试数据,请试一试。

这两个子查询对于获取每篇论文的作者/顾问列表是必要的。

Select
  p.id,
  p.title,
  p_aut.aut_name,
  p_adv.adv_name
From papers p
Left Join (
  Select pp_aut.paper_id,
         Group_Concat(Concat(p_aut.firstname, ' ', p_aut.lastname)) aut_name
  From paper_person_roles pp_aut
  Join persons p_aut On (p_aut.id = pp_aut.person_id)
  Where pp_aut.act_role='AUTHOR'
  Group By pp_aut.paper_id
) p_aut On ( p_aut.paper_id = p.id )
Left Join (
  Select pp_adv.paper_id,
         Group_Concat(Concat(p_adv.firstname, ' ', p_adv.lastname)) adv_name
  From paper_person_roles pp_adv
  Join persons p_adv On (p_adv.id = pp_adv.person_id)
  Where pp_adv.act_role='ADVISER'
  Group By pp_adv.paper_id
) p_adv On ( p_adv.paper_id = p.id )
Group By p.id, p.title