2014-10-06 77 views
0

我想从表的两个独立列中获取不同值的COUNT值。来自表的两个独立列的不同值的MySQL COUNT

我的表是:

ID  CR PB  DB CB  
----------------------------- 
1  1000  1000 
2  60000  1000 
3  1000  (NULL) 
4 1500000  13000 
5  60000  12000 
6  1000  (NULL) 

预期输出:

CR PB cnt_crpb DB CB cnt_dbcb 
1000  3  1000  2 
60000  2  13000  1 
1500000 1  12000  1 

我试图在两个不同的表都列CR PBDB CB分离和使用LEFT JOIN加入了他们,但是没有得到预期输出为MySQL不支持FULL OUTER JOIN。

我也试过使用UNION,但在行中给出了结果。

任何帮助将不胜感激...

谢谢你。

+2

你如何将CR PB和DB DB关联起来,使它们出现在同一行? – Barranka 2014-10-06 15:10:10

+1

@Barranka:看起来OP不希望它们出现在同一行(这是我们所期望的);看起来这些行在“cnt_crpb”和“cnt_dbcb”的递增值上相关(最高值与最高值相关,次高最高,次高),这是一个相当离奇的结果。可以像这样返回结果,但是SQL更容易参与。规范的方法是将计数作为单独的行集返回。 – spencer7593 2014-10-06 15:22:27

回答

2

我认为你需要做到这一点使用union all奇数结果:

select max(CRPB) as CRPB, max(CRPB_cnt) as CRPB_cnt, max(DBCB) as DBCB, max(DBCB_cnt) as DBCB_cnt 
from ((select (@rn1 := @rn1 + 1) as rn, CRPB, count(CRPB) as CRPB_cnt, NULL as DBCB, NULL as DBCB_cnt 
     from table t cross join 
      (select @rn1 := 0) as vars 
     group by CRPB 
    ) union all 
     (select (@rn2 := @rn2 + 1) as rn, NULL, NULL, DBCB, count(DBCB) as DBCB_cnt 
     from table t cross join 
      (select @rn2 := 0) as vars 
     group by DBCB 
    ) 
    ) x 
group by rn; 

这将保证结果不管是哪个名单最长。

+0

这与我将使用的方法类似。 (我的情况稍微复杂一点,我认为规范是通过按降序排列它们来计算“相关”的计数(CRPB的最高计数和DBCB的最高计数,次高的是次高)。我得到计数首先,然后分配了rownum,然后做了UNION ALL这些结果 – spencer7593 2014-10-06 15:38:34

+0

(第二组应该是由DBCB组成的) – spencer7593 2014-10-06 15:55:30

+0

唯一的另外一个问题是这没有处理NULL值,所以它返回一个额外的行[ ** HERE **](http://sqlfiddle.com/#!2/29af0/3)首先要删除空位:)从我+1,但不错的答案! – 2014-10-06 16:03:49

1

请注意,您需要确定哪一列会产生更多的结果,即CR PBDB CB哪一个产生最多结果将是您想要做的第一个选择,然后加入另一个。假设有来自两个

SELECT `CR PB`, cnt_crpb, `DB CB`, cnt_dbcb 
FROM 
( SELECT `CR PB`, COUNT(*) as cnt_crpb, @a := @a + 1 as num_rows_a 
    FROM test_table 
    CROSS JOIN (SELECT @a := 0) temp 
    WHERE `CR PB` is not null 
    GROUP BY `CR PB` 
)t 
LEFT JOIN 
( SELECT `DB CB`, COUNT(*) as cnt_dbcb, @b := @b + 1 as num_rows_b 
    FROM test_table 
    CROSS JOIN (SELECT @b := 0)temp1 
    WHERE `DB CB` is not null 
    GROUP BY `DB CB` 
)t1 ON t1.num_rows_b = t.num_rows_a; 

Fiddle Demo

+0

如果第二个列表比第一个列表长,那么使用“left join”会导致结果丢失。 – 2014-10-06 15:31:13

+1

这是一种方法。一些问题:如果“DB CB”的“独特”值比“CR PB”的“不同”值有多少?执行此语句时,如果udv“@ a”的值为3,该怎么办? (我认为规范是不明确的,行是按照'CR PB'的递增值排序,还是按递减的计数值,'DB CB'的递减值排序。) – spencer7593 2014-10-06 15:32:53

+0

确实行数可能是更多的一方比另一方......关联两个不相关的列并不容易。但这是OP需要在他身边测试的东西。 – 2014-10-06 15:36:07