2014-02-11 36 views
0

一直在这一整天挣扎,并希望寻求帮助如何使这个查询发生。我的问题是,在INNER JOIN子查询的WHERE部分中,我需要使用来自每个正在处理的GC表行的匹配值,显然,子查询不会对主查询一无所知,这就是为什么它会失败。希望你会赶上什么,我想在这里acomplish的想法:子查询的WHERE需求字段从主要查询

SET @now=100; #sunix datetime 
SELECT a.id, b.maxdate 
    FROM GC AS a 
    INNER JOIN (
      SELECT 0 id_group, MAX(dt_active_to) AS maxdate 
       FROM GCDeals 
       WHERE dt_active_from > a.dt_lastused AND dt_active_from <= @now 
       GROUP BY id_group 

       UNION ALL 
       SELECT 1 id_group, MAX(dt_active_to) AS maxdate 
       FROM GCDeals 
       WHERE id_group <> 2 AND dt_active_from > a.dt_lastused AND dt_active_from <= @now 

       UNION ALL 
       SELECT 2 id_group, MAX(dt_active_to) AS maxdate 
       FROM GCDeals 
       WHERE id_group <> 1 AND dt_active_from > a.dt_lastused AND dt_active_from <= @now 
       GROUP BY id_group 
    ) AS b 
    ON a.id_group = b.id_group 

    LEFT JOIN GCMsg AS c 
    ON a.id = c.id_gc 

    WHERE a.is_active = 1 AND a.dt_lastused < @now AND c.id_gc IS NULL 
    ORDER BY a.id 

谢谢

+0

你的选择声明令我困惑。你由id_group分组。所以你的表格GCDeals有一个id_group列。你按它进行分组,然后不管它的值是否用所有结果记录中的零代替。然后你加入所有GCDeals记录的ID为0的每个GC记录?或者是id_group不是GCDeals中的一个列表(我认为MySQL允许这样做)?那你为什么按字面来分组?无论如何,它对我来说并不好看。 –

+0

GCDeals有许多交易分配给这些组0-男女皆宜,1男,2女。表格GC拥有所有的客户,每个客户都属于特定的组。这里棘手的部分是,如果客户在0组中,maxdate被发现为0,1,2组(因为男女皆宜涵盖了所有三组 - 本身,男性和女性),如果在1 - 然后为0,1 ..如果在2-然后0,2 ..这就是为什么内部连接子查询实际上去,并发现这些值的方式。 – Maris

+0

子查询实际上总是返回两行两列的行:id_group,maxdate。 id_group始终为0,1,2,并计算maxdate(0和1和2)(0和1)(0和2) – Maris

回答

1

好吧,我希望我已经明白你原来的SQL现在。你想要所有的GC与最后适当的最大日期。你认为合适的取决于gc.dt_lastused和gc.id_group。

select id, 
(
    select max(dt_active_to) 
    from gcdeals 
    where dt_active_from > gc.dt_lastused and dt_active_from <= @now 
    and 
    (
    gc.id_group = 0) 
    or 
    (gc.id_group = 1 and gcdeals.id_group <> 2) 
    or 
    (gc.id_group = 2 and gcdeals.id_group <> 1) 
) 
) as maxdate 
from gc 
where is_active = 1 and dt_lastused < @now 
and id not in (select id_gc from gcmsg) 
order by id; 

编辑:因此,而不是连接表一起,你应该在一个子查询中选择每条记录的最大日期下面是一个使用加入相同的语句,提供选择MAX(dt_active_from)和最小(dt_active_to)在一通:

select gc.id, max(gcd.dt_active_from), min(gcd.dt_active_to) 
from gc 
left outer join gcdeals gcd 
    on gc.id = gcd.id_gc 
    and gcd.dt_active_from > gc.dt_lastused and gcd.dt_active_from <= @now 
    and 
    (
    gc.id_group = 0) 
    or 
    (gc.id_group = 1 and gcd.id_group <> 2) 
    or 
    (gc.id_group = 2 and gcd.id_group <> 1) 
) 
where gc.is_active = 1 and gc.dt_lastused < @now 
group by gc.id 
order by gc.id; 

你看,一旦你发现了如何子查询中选择所需的值,这是不是太硬,改变成一个加入。你可以通过两个步骤获得你正在寻找的东西。另一方面,如果你从加入思考开始,相同的任务可能相当抽象。

至于执行计划:说GC有1000个活动记录,通常在GCDeals中有大约10个合适的匹配。然后第一条语句选择1,000条记录,并在每条记录上使用循环来访问GCDeals聚合值。第二条语句将每条记录加入1,000条GC记录,每条记录有10条GCDeals记录,从而获得10,000条记录,然后将它们汇总为再次记录1,000条记录。也许循环更快,也许连接。这取决于。但是,比方说,GC拥有100万条活跃的记录,并且在每条记录中,您预计有1000条GCDeals匹配,那么第一条语句可能非常缓慢,必须循环很多次。但第二条语句会创建十亿条中间记录,这可能会导致内存问题,并导致执行速度非常慢,甚至导致内存不足错误。所以知道这两种技术都可用,这是很好的。

+0

谢谢,将给这个试一试,看看它是否有效:)手指划过 – Maris

+0

它实际上工作..除了一个小失踪“(”这是不相关的,现在我看到在这个背后的逻辑..是的,完全不同的思维方式比我最初的方法。非常感谢,并真正感谢你的时间! – Maris

+0

还有一个问题...如果我想修改查询的开始像这样:SELECT如果包含两个理想结构来检索MAX(dt_active_from),而另一个结合MIN(dt_active_to),那么是否可以使用SELECT MAX(dt_active_from),MIN(dt_active_to)?你的表现会受到很大的影响吗? – Maris