从2个不同的列中查找最后一位相同的数字

时间:2018-10-31 09:03:48

标签: sql oracle

我有2列电话号码,要求是获取最后8位数字相同的号码。列A的数字为11位,列B的数字为9位或10位。 我尝试使用 SUBSTR Like 向左函数来解决,但问题是数据太大,我无法使用它方式。

select trunc(ta.timeA), ta.columnA
from table1A ta,
     tableB tb
WHERE substr(ta.columnA,-8) LIKE substr(tb.columnB,-8)
  and trunc(ta.timeA) = trunc(ta.timeB)
  AND trunc(ta.timeA) >= TO_DATE('01/01/2018', 'dd/mm/yyyy')
  AND trunc(ta.timeA) < TO_DATE('01/01/2018', 'dd/mm/yyyy') + 1
GROUP BY ta.columnA, trunc(ta.timeA)  

3 个答案:

答案 0 :(得分:1)

您要从表A中进行选择,因此执行此操作。不要参加您只想选择tableB中具有匹配项的tableA行。因此,在您的EXISTS子句中放置一个WHERE子句。

select trunc(timea), columna
from table1a ta
where trunc(timea) >= date '2018-01-01'
  and trunc(timea) < date '2018-01-02'
  and exists
  (
    select *
    from tableb tb
    where trunc(tb.timeb) = trunc(ta.timea)
    and substr(tb.columnb, -8) = substr(ta.columna, -8)
  )
order by trunc(timea), columna;

为了快速运行,创建以下索引:

create idxa on tablea( trunc(timea), substr(columna, -8) );
create idxb on tableb( trunc(timeb), substr(columnb, -8) );

但是,我不明白为什么您如此渴望快速运行它。您是否要保留所有数据并再次运行查询?应该有一个更好的解决方案。首先想到的是将区号和数字分成两个单独的列。

更新:仍然比建议的idxa更快,它应该是tableA的覆盖索引:

create idxa on tablea( trunc(timea), substr(columna, -8), columna );

这里,DBMS只能使用索引,而不必访问表。因此,以防万一上述情况对您来说仍然太慢,您可以尝试使用更改后的索引。

正如Alex Poole在下面的评论中指出的那样,应该是

where trunc(timea) = date '2018-01-01'

仅,如果您要查看的范围始终是一天,如示例中所示。

答案 1 :(得分:0)

您可以在下面尝试使用= operator代替like operator

您要匹配的最后两位数字

select trunc(ta.timeA),ta.columnA 
from table1A ta inner join tableB tb 
on substr(ta.columnA,-8) = substr(tb.columnB,-8)
and trunc(ta.timeA) = trunc(ta.timeB)
AND trunc(ta.timeA) >= TO_DATE('01/01/2018', 'dd/mm/yyyy')
AND trunc(ta.timeA) < TO_DATE('01/01/2018', 'dd/mm/yyyy') + 1 
GROUP BY ta.columnA, trunc(ta.timeA)  

答案 2 :(得分:0)

如果您更具体地了解您的SQL环境,将更容易获得帮助,以下是有关此查询的一些建议,这些建议适用于大多数环境。

在处理大数据集时,性能变得尤为重要,而技术上的细微变化也会产生重大影响。

例如: 像通常用于通配符的部分匹配一样,您不是说等于吗? Like慢于平等,如果您不使用通配符,我建议您寻找平等。

此外,您最初是从(叉/笛卡尔积)连接开始的,但是随后您的where子句定义了非常特定的匹配条件(匹配时间字段),如果需要匹配的时间字段,请使其成为表连接的一部分,这将减少联接结果的数量,这将大大缩小数据集,然后需要将其他条件应用于该数据集。

此外,在where子句中使用日期计算的值很慢。最好在查询之前设置一个@fromDate和@toDate参数,然后在where子句中使用这些参数,然后是不需要为每一行计算的文字。