具有已连接子查询的列范围

时间:2012-01-22 15:38:41

标签: mysql join subquery

我必须选择一个计数列,按两个来源的日期分组。我将结果集作为子查询加入。然而,结果是假的。我发现问题与JOIN .. ON子句有关。此查询工作正常:

SELECT id
FROM pu a 
LEFT JOIN (
    SELECT 
        COUNT(pd.id) AS c_id1, 
        NULL AS c_id2,
        LEFT(pd.start_date, 10) AS date,
        pd.pid 
    FROM 
        p_d pd
    **WHERE pd.pid = 111**
    GROUP BY date

    UNION 

    SELECT 
        NULL AS c_id1,
        COUNT(pd.id) AS c_id2,
        LEFT(pd.inactivation_date, 10) AS date, 
        pd.pid
    FROM 
        p_d pd
    **WHERE pd.pid = 111**
    GROUP BY date
) x
ON x.pid = a.id;

但是这个(没有WHERE子句)返回一个错误的结果集:

SELECT id
FROM pu a 
LEFT JOIN (
    SELECT 
        COUNT(pd.id) AS c_id1, 
        NULL AS c_id2,
        LEFT(pd.start_date, 10) AS date,
        pd.pid 
    FROM 
        p_d pd
    GROUP BY date

    UNION 

    SELECT 
        NULL AS c_id1,
        COUNT(pd.id) AS c_id2,
        LEFT(pd.inactivation_date, 10) AS date, 
        pd.pid
    FROM 
        p_d pd
    GROUP BY date
) x
ON x.pid = a.id;

可以在加入的子查询中以某种方式使用a.id吗?现在是“未知专栏”。

1 个答案:

答案 0 :(得分:2)

在您的子查询中,您使用的pd.pid SELECT列不属于GROUP BY且未汇总。这样的列称为hidden,在标准SQL中,这会产生语法错误,但mysql允许它,尽管可以从每个组中的任何行中自由选择值。

如果使用WHERE pd.pid = 111限制集合,则组中pd.pid的所有值都将相同,因此无论使用哪一行来获取它都无关紧要,但不使用WHERE pd.pid的值将是未定义的(mysql可能会选择能够最快获取的那个)。你也将这个未定义的pid用于JOIN,这样你就会得到错误的结果。

http://dev.mysql.com/doc/refman/5.6/en/group-by-hidden-columns.html

但是很难说你应该如何重写你的查询,因为你没有提供关于表模式的足够信息,你想要实现什么以及你的表/列名称是什么意思。