2012-01-04 64 views
3

我需要一个表来比较两列,并给予3件事情比较2列:在同一个表

  • 行计数检查(已检查共行)的匹配行
  • 计数(行,其中两列匹配)
  • 计数行的不同(行,其中两列差异)

我已经能够使用连接自己来匹配行,但我不确定如何一次获得其他所有行。同时获取所有信息的重要性是因为这是一个非常活跃的表格,并且数据以很高的频率变化。

我无法发布表架构,因为其中有大量与此问题无关的数据。有问题的列都是int(11) unsigned NOT NULL DEFAULT '0'。为此,我会给他们打电话maskmask_alt

+0

你能否提供一些关于“匹配”,“不同”和“检查”的含义的更多信息? – Bohemian 2012-01-04 00:24:44

+0

可以请你发表你的表格架构吗? – 2012-01-04 00:30:03

+0

@johntotetwoo我不能,但我确实添加了更多关于它的细节。 – Jericon 2012-01-04 01:14:01

回答

4
select 
    count(*) as rows_checked, 
    sum(col = col2) as rows_matching, 
    sum(col != col2) as rows_different 
from table 

注高雅使用sum(condition)
这是可行的,因为在mysql true1false0。总结这些计数条件为true的次数。它比case when condition then 1 else 0 end要优雅得多,这是编码为if (condition) return true else return false;的SQL等效代码,而不是简单的return condition;

+0

现在试试这个。我只限于过去的一天。不幸的是,我必须限制的一些列没有编入索引,因此这导致大约300 M行的全表扫描:S – Jericon 2012-01-04 01:20:37

+0

是否有一种方法可以最初使用索引列来限制行,然后*运行上述。例如,如果您确信限制出现在数据的最后一周内,请首先选择上周的数据作为内部别名查询,然后查询结果。 – Bohemian 2012-01-04 01:42:18

+0

我拿回来了,我限制的几列被索引,但是他们没有很高的基数。在这张表中的8亿行中,几乎有400M必须被扫描。其中,有143场M比赛。这只是过去10周的结果。 – Jericon 2012-01-04 05:56:34

2

假设你的意思是你要算其中col1是或不是等于col2行,你可以使用聚合SUM()加上CASE

SELECT 
    COUNT(*) AS total, 
    SUM(CASE WHEN col = col2 THEN 1 ELSE 0 END)AS matching, 
    SUM(CASE WHEN col <> col2 THEN 1 ELSE 0 END) AS non_matching 
FROM table 

它可能是更有效地获得总COUNT(*)在一个子查询中,如果上面的表达不够好,那么使用该值减去匹配以获得不匹配。

SELECT 
    total, 
    matching, 
    total - matching AS non_matching 
FROM 
(
    SELECT 
    COUNT(*) AS total, 
    SUM(CASE WHEN col = col2 THEN 1 ELSE 0 END)AS matching 
    FROM table 
) sumtbl