MySQL:选择多个子查询的结果时,“子查询返回多个行”

时间:2018-12-19 19:23:05

标签: mysql subquery

在运行查询时出现“ Subquery returns more than 1 row”错误,该查询旨在返回两个子查询的结果。为什么在这里返回多个行是一个问题,如何解决这个问题?

数据表和相关字段如下:

Accounts
id

Meetings
account_id
signed_user_id
开始日期

Users
id
姓氏

会议分配给一个帐户和一个用户。我正在尝试创建一个表,该表将显示会议开始日期在不同日期范围内的每个帐户每个分配的用户的会议数量。日期范围应与包含以下标题的表格安排在同一行中:

帐户|用户的姓氏|未来1-31天的会议|将来31至60天开会

如下图所示:

this image

这是我的查询

SELECT
(SELECT
    a.name
  FROM
    accounts AS a
  JOIN
    meetings AS m ON a.id = m.account_id
    AND date_start BETWEEN CURDATE() AND DATE_ADD(CURDATE(),INTERVAL 60 DAY)
  JOIN
    users AS u ON m.assigned_user_id = u.id
  WHERE
    m.status = 'Planned'
    AND m.deleted = 0
GROUP BY a.id, u.id) AS 'Account',
(SELECT
    u.last_name
  FROM
    accounts AS a
  JOIN
    meetings AS m ON a.id = m.account_id
    AND date_start BETWEEN CURDATE() AND DATE_ADD(CURDATE(),INTERVAL 60 DAY)
  JOIN
    users AS u ON m.assigned_user_id = u.id
WHERE
    m.status = 'Planned'
    AND m.deleted = 0
GROUP BY a.id, u.id) AS 'Name',
(SELECT
    COUNT(m.id)
  FROM
    accounts AS a
  JOIN
    meetings AS m ON a.id = m.account_id
    AND date_start BETWEEN CURDATE() AND DATE_ADD(CURDATE(),INTERVAL 30 DAY)
  JOIN
    users AS u ON m.assigned_user_id = u.id
  WHERE
    m.status = 'Planned'
    AND m.deleted = 0
GROUP BY a.id, u.id) AS 'Meetings 1-30 days',
(SELECT
    COUNT(m.id)
  FROM
    accounts AS a2
  JOIN
    meetings AS m ON a.id = m.account_id
    AND m.date_start BETWEEN DATE_ADD(CURDATE(),INTERVAL 31 DAY) AND DATE_ADD(CURDATE(),INTERVAL 60 DAY)
  JOIN
    users AS u ON m.assigned_user_id = u.id
  WHERE
    m.status = 'Planned'
    AND m.deleted = 0
GROUP BY a.id, u.id) AS 'Meetings 31-60 days'

必须将包含帐户名称和用户名称的列添加为子查询,以避免出现“ Operand should contain 1 column(s)”错误。与会议计数对应的列必须是子查询,因为联接表的任何一行都不能同时适合两个日期范围。单独运行时,每个子查询均返回预期结果。但是,如图所示将子查询放在一起时,我得到“ Subquery returns more than 1 row”。我尝试为每个子查询分配不同的别名,但这没有帮助。

1 个答案:

答案 0 :(得分:1)

SQL查询不返回嵌套结果集;因此SELECT子句中使用的表达式(例如子查询)不能有多个值,因为那样会“嵌套”它的值。您很可能只需要使用条件聚合,如下所示:

SELECT a.id, u.id, a.name, u.last_name
    , COUNT(CASE WHEN m.date_start BETWEEN CURDATE() AND DATE_ADD(CURDATE(),INTERVAL 30 DAY) THEN 1 ELSE NULL END) AS `Meetings 1-30 days`
    , COUNT(CASE WHEN m.date_start BETWEEN DATE_ADD(CURDATE(),INTERVAL 31 DAY) AND DATE_ADD(CURDATE(),INTERVAL 60 DAY) THEN 1 ELSE NULL END) AS `Meetings 31-60 days`
    , COUNT(CASE WHEN  THEN 1 ELSE NULL END) AS 
FROM accounts AS a
JOIN meetings AS m ON a.id = m.account_id
JOIN users AS u ON m.assigned_user_id = u.id
WHERE m.status = 'Planned' AND m.deleted = 0
  AND m.date_start BETWEEN CURDATE() AND DATE_ADD(CURDATE(),INTERVAL 60 DAY)
GROUP BY a.id, u.id, a.name, u.last_name
;

注意: ELSE NULL 在技术上是自动的,可以省略;只是为了清楚起见。聚合函数(例如COUNT)会忽略NULL值;空值影响此类函数的唯一时间是它们仅遇到空值(在这种情况下,其结果为空)。

旁注:您可以继续以类似原来的形式进行查询;如果您将分组字段包括在子查询的结果中,则这些子查询可能已经合并在一起(但是,这可能是帐户,会议和用户的大量多余连接)。