mysql - 子子查询在父选择中找不到连接列

标签 mysql join subquery

我在使用 SQL 时遇到了一些麻烦: 基本上,我试图获取一个结果集,其中包含向员工提出的所有问题(按公司分组)的总和,并添加“onetime_items”,这是在不同的表中手动添加的项目。

我目前有这个 SQL 语句(我正在使用 MySQL):

SELECT 
CONCAT_WS(
    ', ', count(DISTINCT CONCAT(emailaddress, '_', a.id)),
    (
        SELECT GROUP_CONCAT(items SEPARATOR '; ') as OneTimeItems
        FROM ( 
            SELECT CONCAT_WS(
                ': ', oi.item_name, SUM(oi.item_amount)
            ) items 
            FROM onetime_item oi 
            WHERE oi.company_id = e.company_id
            AND oi.date BETWEEN '2015-12-01'
            AND LAST_DAY('2015-12-01') 
            GROUP BY oi.item_name 
        ) resulta
    )
) as AllItems,
e.id,
LEFT(e.firstname, 1) as voorletter,
e.lastname
FROM question q 
LEFT JOIN employee e ON q.employee_id = e.id 
WHERE 1=1 
AND YEAR(created_at) = '2015'
AND MONTH(created_at) = '12' 
GROUP BY e.company_id

现在我收到以下错误:

Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42S22]: Column not found: 1054 Unknown column 'e.company_id' in 'where clause'

使用的日期是虚拟日期。

此列确实存在于表员工中,并且左连接有效(我尝试手动输入 ID,而不是使用列引用,它有效,我得到了正确的结果)

知道为什么对 e.company_id 的引用失败吗?

最佳答案

感谢 dba.stackexchange.com

链接:https://dba.stackexchange.com/questions/126339/subquery-cant-find-column-from-superquerys-join

回答者ypersillycubeᵀᴹ

<小时/>

这是发布在那里的答案,希望其他人也能从中受益! 问题原因由 @Phil in the comments 确定。 : 在评论中: 可能是因为嵌套太深 您有 2 层嵌套,并且表 e 的引用无法“看到”MySQL 中的这 2 层。

相关的内联子查询通常可以转换为派生表,然后在 FROM 子句中 LEFT 连接到其他表,但它们必须变成不相关(在 MySQL 中。在其他 DBMS 中,您可以使用 LATERAL 连接或类似的方法)外部应用。

第一次重写以完成工作:

  SELECT 
       CONCAT_WS(
           ', ', count(DISTINCT CONCAT(q.emailaddress, '_', e.id)),
           dv.OneTimeItems
       ) as AllItems,
       e.id,
       LEFT(e.firstname, 1) as voorletter,
       e.lastname
   FROM question q 
   LEFT JOIN employee e ON q.employee_id = e.id 
   LEFT JOIN
       (
          SELECT company_id,
                 GROUP_CONCAT(items SEPARATOR '; ') AS OneTimeItems
          FROM ( 
               SELECT oi.company_id,
                     CONCAT_WS(
                ': ', oi.item_name, SUM(oi.item_amount)
            ) items 
            FROM onetime_item oi 
            WHERE oi.date BETWEEN '2015-12-01'
                              AND LAST_DAY('2015-12-01') 
            GROUP BY oi.company_id, oi.item_name 
        ) resulta
        GROUP BY company_id
    ) AS dv
    ON dv.company_id = e.company_id
WHERE 1=1 
AND YEAR(q.created_at) = '2015'
AND MONTH(q.created_at) = '12' 
GROUP BY e.company_id ;

测试SQLfiddle

与问题评论无关:

有 GROUP BY e.company_id,而选择列表有 e.id、LEFT(e.firstname, 1)、e.lastname。所有这些都会给出来自每家公司的(或多或少随机)员工的任意结果 - 甚至在极少数情况下,来自 2 或 3 个不同员工的任意结果! MySQL 允许(5.7 之前)对 group by 的错误使用,这可能会导致错误的结果。它已在 5.7 中修复,默认设置将拒绝此查询。 条件:

YEAR(created_at) = '2015' AND MONTH(created_at) = '12'

无法使用索引。如果列是 DATE 类型或具有包含-排除范围条件,最好使用 BETWEEN 重写,这可以完美地处理任何精度的任何日期时间类型(DATE、DATETIME、TIMESTAMP):

-- 仅当类型仅是 DATE 时使用

date BETWEEN '2015-12-01' AND LAST_DAY('2015-12-01')

或者:

-- 当类型为 DATE、DATETIME 或 TIMESTAMP 时使用

created_at >= '2015-12-01' AND created_at < '2016-01-01' 

关于mysql - 子子查询在父选择中找不到连接列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34789982/

相关文章:

php - 在 Laravel Eloquent 中查询只有日期的日期时间字段

php - 在 CodeIgniter 中检索数据库表注释

php - 两个相同模型/表之间的两种关系

mysql - 如何避免使用子查询在 MySQL 中多次运行一个大表?

mysql - 比较MySQL同一列的计数以获得百分比

mysql - SQL 使用复合主键填充自定义表

mysql - 计算未查看帖子的数量

laravel - 条件表连接

mysql - SQL select 将两列合并为一列

mysql比较列和子查询