子查询的替代方案

时间:2012-06-25 14:42:16

标签: mysql sql

我正在使用Mysql 5.1,并且有这个查询,有没有办法不使用子查询并完成相同的结果?

SELECT oref.affiliate_id, ROUND(sum( oph.amount ) * 0.10 ,2) AS tsum
FROM operators_referer AS oref 
LEFT JOIN operators_payments_history AS oph 
ON oref.operator_id = oph.operator_id
WHERE oref.affiliate_id = 28221
AND
(
    oph.date_paid > 
    (
        SELECT MAX(aph.date_paid) 
        FROM affiliates_payments_history AS aph 
        WHERE aph.operator_id = oref.affiliate_id
    )
    OR 
    (
        SELECT MAX(aph.date_paid)
        FROM affiliates_payments_history AS aph 
        WHERE aph.operator_id = oref.affiliate_id 
    ) 
    is NULL
)

5 个答案:

答案 0 :(得分:3)

不要这样做! 如果表被正确编入索引,并且数据库结构有意义,那么使用子查询几乎肯定会更好。按照你的评论,似乎这会简化并加快速度 - 但这并不一定如此。使用非子查询形式,解析器不一定能做得更好。子查询的清晰度,以及重写不使用子查询的查询的复杂性,都认为这不是一个有价值的目标。

你需要知道它是否可以完成?它可以: this CS.stackexchange问​​题的答案显示了如何执行此操作,并且有人指出无法将子查询编写为基于连接的查询,没有可能的设置差异。这意味着有一种方法可以简化它,并且一些与算术方法相关联的链接也与之相关联。

答案 1 :(得分:2)

您是否尝试过HAVING条款?

SELECT oref.affiliate_id, ROUND(sum( oph.amount ) * 0.10 ,2) AS tsum
FROM operators_referer AS oref 
LEFT JOIN operators_payments_history AS oph 
ON oref.operator_id = oph.operator_id
LEFT JOIN affiliates_payments_history AS aph
ON aph.operator_id = oref.affiliate_id
WHERE oref.affiliate_id = 28221
GROUP BY oref.affiliate_id
HAVING MAX(aph.date_paid) > oph.date_paid OR MAX(aph.date_paid) IS NULL

答案 2 :(得分:1)

试试这个::

  SELECT oref.affiliate_id, ROUND(sum( oph.amount ) * 0.10 ,2) AS tsum
    FROM operators_referer AS oref 
    LEFT JOIN operators_payments_history AS oph 
    ON oref.operator_id = oph.operator_id
   LEFT JOIN affiliates_payments_history AS aph ON aph.operator_id = oref.affiliate_id
    WHERE oref.affiliate_id = 28221
  GROUP BY oref.affiliate_id
  HAVING IFNULL(MAX(aph.date_paid),0 > oph.date_paid)

答案 3 :(得分:1)

SELECT MAX(aph.date_paid) AS max_aph, 
       oref.affiliate_id, 
       ROUND(sum( oph.amount ) * 0.10 ,2) AS tsum
FROM operators_referer AS oref 
LEFT JOIN operators_payments_history AS oph 
       ON oref.operator_id = oph.operator_id
LEFT JOIN affiliates_payments_history AS aph 
       ON aph.operator_id = oref.affiliate_id
WHERE oref.affiliate_id = 28221
AND (oph.date_paid > max_aph OR max_aph is NULL)

没试过,但我认为这就是你要搜索的内容。

答案 4 :(得分:1)

您正在寻找的是一个简单的JOIN逻辑。

像这样:

SELECT oref.affiliate_id, ROUND(sum( oph.amount ) * 0.10 ,2) AS tsum
FROM operators_referer AS oref 
     LEFT JOIN operators_payments_history AS oph 
            ON oref.operator_id = oph.operator_id
     LEFT JOIN affiliates_payments_history AS aph
            ON aph.operator_id = oref.affiliate_id
WHERE oref.affiliate_id = 28221
AND ( oph.date_paid > MAX(aph.date_paid)
OR MAX(aph.date_paid) IS NULL)    
GROUP BY oref.affiliate_id;

查询的含义基本上是“将aph和oph表连接到oref,仅在oref.affiliate_id的范围内应用max函数,并查找条件适用的行”

在MySQL手册中了解有关JOINLEFT JOIN功能的更多信息是明智的