如何解析返回超过1行的子查询

时间:2014-03-29 12:04:08

标签: mysql sql many-to-many subquery

我知道这些问题很多,但我无法在其他地方找到明确的答案。

我有4张桌子:

  • person_per
  • person2group2role_p2g2r
  • group_grp
  • list_lst

我想运行查询,显示有关某人的所有信息,包括他们所在的群组类型

per_ID位于person_per

多对多网桥包含per_IDgrp_IDrole_ID

grp_ID位于group_grp

grp_type表格中的group_grplst_optionID

相关联

lst_OptionName是文本中的名称(我最终想要显示的内容)

我试过两种方式,在两者中都遇到同样的错误。选项1使用WHERE args链接表,而选项2使用JOIN语句。 这都在第二个子查询中。主要问题是提取个人信息,第一个子查询正在拉动人的分类。

选项1:

SELECT person_per.per_ID as AddToCart, CONCAT(person_per.per_FirstName, ' ', person_per.per_MiddleName) AS 'FirstNames', person_per.per_LastName AS 'Surname', 
    (SELECT lst_OptionName FROM list_lst WHERE list_lst.lst_ID=1 AND
        list_lst.lst_OptionID=person_per.per_cls_ID) AS "Classification",
    person_per.per_HomePhone AS 'Tel', person_per.per_WorkPhone AS 'Cell',
    person_per.per_Email AS 'Email',
    --START DIFF
    (SELECT lst_OptionName 
    FROM list_lst, person2group2role_p2g2r, group_grp, person_per 
    WHERE list_lst.lst_ID=3 
        AND person_per.per_ID = person2group2role_p2g2r.p2g2r_per_ID 
        AND person2group2role_p2g2r.p2g2r_grp_ID = group_grp.grp_ID 
        AND group_grp.grp_Type = list_lst.lst_ID) AS "LifeGroupType"
    --END DIFF
FROM person_per
ORDER BY person_per.per_LastName

选项2:

SELECT person_per.per_ID as AddToCart, CONCAT(person_per.per_FirstName, ' ', person_per.per_MiddleName) AS 'FirstNames', person_per.per_LastName AS 'Surname',
    (SELECT lst_OptionName FROM list_lst WHERE list_lst.lst_ID=1 AND
        list_lst.lst_OptionID=person_per.per_cls_ID) AS "Classification",
    person_per.per_HomePhone AS 'Tel', person_per.per_WorkPhone AS 'Cell',
    person_per.per_Email AS 'Email',
    --START DIFF
    (SELECT lst_OptionName 
    FROM list_lst 
        JOIN group_grp ON group_grp.grp_Type = list_lst.lst_ID
        JOIN person2group2role_p2g2r ON person2group2role_p2g2r.p2g2r_grp_ID = group_grp.grp_ID
        JOIN person_per ON person_per.per_ID = person2group2role_p2g2r.p2g2r_per_ID
    WHERE list_lst.lst_ID=3) AS "LifeGroupType"
    --END DIFF
FROM person_per
ORDER BY person_per.per_LastName

我知道这是一个问题,因为每个人都可以分配到多个群组,我只是想知道如何分割不同的群组。 优先结果将是每人一行,包括他们所有的信息以及他们所在的组。 否则我将如何

  1. 将多个子查询结果CONCAT到单个字段
  2. 为该人的不同群体设置不同的行
  3. 任何信息都会令人惊叹:)

2 个答案:

答案 0 :(得分:2)

我将假设问题是子查询返回多行,因为每个表中有多个项目。然后,我将假设您正在使用MySQL。解决方案是一个名为group_concat()的函数:

SELECT p.per_ID as AddToCart, CONCAT(p.per_FirstName, ' ', p.per_MiddleName) AS FirstNames, 
       p.per_LastName AS Surname, 
       (SELECT group_concat(lst_OptionName)
        FROM list_lst l
        WHERE l.lst_ID = 1 AND l.lst_OptionID = p.per_cls_ID
       ) AS Classification,
       p.per_HomePhone AS Tel, p.per_WorkPhone AS Cell, p.per_Email AS Email,
    --START DIFF
       (SELECT lst_OptionName 
        FROM person2group2role_p2g2r p2g join
             group_grp g
             on p2g.p2g2r_grp_ID = g.grp_ID join
             list_lst l
             on g.grp_Type = l.lst_ID
        WHERE l.lst_ID = 3 and p.per_ID = p2g.p2g2r_per_ID
       ) AS LifeGroupType
    --END DIFF
FROM person_per p
ORDER BY p.per_LastName;

在此过程中,我还添加了表别名,以使查询更具可读性,显式join语法,并删除子查询中对person_per的额外不必要的引用。这可能是你问题的原因。

答案 1 :(得分:0)

您在子查询中选择了多个值,而应该只有一个。

尝试在子查询中使用LIMIT 1将解决它。或者你必须选择你需要的值,但它必须是一个值。

  SELECT person_per.per_ID as AddToCart         ,       (SELECT .......)
            ^^^^^^^^^^^^^--- you selecting 1value here     ^^^^^^
                                                         |____you should select here also one value