2012-12-27 26 views
0

基本上,我有三个表:如何根据引用第三个表的条件排除数据,如何连接两个表?

  • CDR,它包含字段dst(目的地),billsec(持续时间),和calldate
  • Intlrates,其中包含code(国家代码),和cost(每分钟)。
  • areacode,其中包含areacode,statecity

目前我有添加了调用每个代码的总成本,以下声明:

SELECT 
    mapgtalkexten.Intlrates.`Code`, 
    sum(mapgtalkexten.Intlrates.Cost * (cdr.billsec/60)) as totals 
FROM 
    cdr JOIN mapgtalkexten.Intlrates ON  
    ((`Code` = SUBSTRING(dst, 4, 3) or `Code` = SUBSTR(dst, 4, 2)) 
    and dst like "011%") 
    --The above limits the join to only calls where the destination phone number 
    --requires the exit code (011) and the country code is 2 or 3 digits  
    or (`Code` = SUBSTR(dst, 2, 3) and dst like "1%") 
    --The above was written to also join countries where the NANP format was used 
    --(i.e. +1787 for Puerto Rico.)  
WHERE 
    cdr.calldate like "2012-11%" 
    and billsec >0 
GROUP BY 
    mapgtalkexten.Intlrates.`Code` 

输出的样本:

Code | totals 
-------------- 
212 | 2.035 
240 | 170.76 
352 | 2.268 
49 | 0.45 

现在,我的问题是这样的:在NANP和非NANP代码之间,表没有区别。这意味着在我的加入中,两者都是:

011212(摩洛哥)和1212(纽约州)都增加到总数。第一个是好的,第二个在不应该的时候增加总数。

为了避免这种情况,有没有办法修改为连接成线沿线的东西第二个条件:

`Code` = SUBSTR(dst, 2, 3) AND SUBSTR(dst, 2, 3) != areacode.areacode 

基本上使得它,这样它只会如果代码匹配和代码加入不在国家区号表中。

我认为有一种方法可以通过连接(或者可能存在)来实现,但是当涉及到数据库时我很不足,而且我完全不知道如何去实现它。对不起,如果有更多的信息你需要/这个问题是荒谬的。

+0

顺便说一句。使用'LIKE'是一个计算负担(字符串比较+通配符)。你的cdr。像“2012-11%”一样可以重写为“YEAR(cdr.calldate)= 2012 AND MONTH(cdr.calldate)= 11'。还有一个优化的机会,因为你可以在你的表上为一年和一个月声明一些额外的索引,即使它们都来自同一列中的值。 –

回答

0

你可以在你的SELECT的末尾添加HAVING语句,如下所示

HAVING `Code` = SUBSTR(dst, 2, 3) AND SUBSTR(dst, 2, 3) != areacode.areacode 
+0

当我尝试这样做时,我得到“未知列”areacode.areacode' – Valkyrio

+0

这是因为'HAVING'子句中使用的任何内容都必须在GROUP BY子句中声明,并且AFAIK也必须在select子句中声明 –

+0

你应该改变你的最后一个OR子句,如下:或('Code' = SUBSTR(dst,2,3),dst如“1%”AND SUBSTR( dst,2,3)不在(从地区代码中选择地区代码)) – augustzf

1

当使用通配符列选择*你所有列的所有在连接操作中使用的表。如果您指定通配符允许的表格,您只能从这些表格中获取列。

知道即使您加入(并过滤)了三张表,也可以从两张表中选择信息。

SELECT  t1.*, 
       t2.* 
    FROM  table_1 AS t1 
    LEFT JOIN table_2 AS t2 
     ON /*clauses*/ 
    LEFT JOIN table_3 AS t3 
     ON /*clauses*/ 
    WHERE t3.column = value; 
+0

您的帖子刚刚被标记为“低质量”,这可能是因为您没有解释您的答案,可以通过解释为什么答案问题,我之所以这样说,是因为我根本看不懂你的代码......空白是真的让人困惑。 – Ben

+0

谢谢!你的意思是代码缩进是令人困惑的吗? –

+0

是的,我做了...它是个人喜好,但我觉得它d如果难以阅读。其他人当然也许不会。 – Ben

-2

你会想是这样的:

select results.* 
from 
( 
    --two table query here 
)results,third_table 
    where third_table.foo = results.bar 
    --filter third table here 

这样做是产生的结果集的前两个表中,然后剥离其中third_table满足条件的记录。

+1

-1从子查询中选择使用比使用正确连接更多的内存,因为它改变了操作的顺序,并且不允许查询优化器为优化进行规划。 –

+1

@MihaiStancu这是我在StackOverflow任职期间阅读过的最不正确的陈述之一。如果数据被编入索引,CBO将尽其所能。进一步使用更多的内存也是非常不正确的。 – Woot4Moo

+2

AFAIK查询/加入视图不使用基表的索引,除非在特定条件下。选择指定多个表的查询的处理方式与其等效的连接查询完全相同。但是子查询需要事先执行,并且它们提供的数据被用于加入和过滤,就像视图一样 - 而不需要访问它们的索引。 –

相关问题