计算一个数字出现的次数

时间:2013-07-06 09:15:43

标签: sql sql-server-2008 tsql

我想从我的表中计算每个数字的所有可能组合。

我希望我的查询返回这样的内容:

Number (Value)     Count
       1            39
       2            450
       3            41

我的表格如下:

enter image description here

当我运行以下查询时:

SELECT *
FROM dbo.LottoDraws ld
JOIN dbo.CustomerSelections cs
ON ld.draw_date = cs.draw_date

CROSS APPLY(
  SELECT COUNT(1) correct_count
  FROM (VALUES(cs.val1),(cs.val2),(cs.val3),(cs.val4),(cs.val5),(cs.val6))csv(val)
  JOIN (VALUES(ld.draw1),(ld.draw2),(ld.draw3),(ld.draw4),(ld.draw5),(ld.draw6))ldd(draw)
  ON csv.val = ldd.draw WHERE ld.draw_date = '2013-07-05'
)CC
ORDER BY correct_count desc

我得到这样的东西:

enter image description here

3 个答案:

答案 0 :(得分:5)

我提供此解决方案,因为unpivot通常比一系列union all表现更好。原因是每个union all可以导致全表扫描,而unpivot可以通过单次扫描完成。

所以,你可以写下你想要的东西:

select val, count(*)
from (select pk, val
      from test
      unpivot (val for col in (val1, val2, val3, val4, val5, val6)
              ) as unpvt
     ) t
group by val
order by val;

答案 1 :(得分:4)

假设我确实理解了您的需求,我通过以下方式解决了问题。 我的假设是你需要计算一个值在val列(val1,val2,val3等等)上出现的单个值的无关紧要。

这是我的测试数据:

CREATE TABLE Test(
pk int PRIMARY KEY IDENTITY(1,1) NOT NULL,
val1 int, val2 int, val3 int, val4 int, val5 int, val6 int
)

INSERT INTO Test
SELECT 1,2,3,4,5,6 UNION ALL
SELECT 1,2,3,4,5,6 UNION ALL
SELECT 1,2,3,4,5,6 UNION ALL
SELECT 1,2,3,4,5,6 UNION ALL
SELECT 3,3,3,3,3,3 UNION ALL
SELECT 1,2,3,4,5,7

这是返回单个val发生次数的查询:

SELECT v, SUM(c) FROM (
    SELECT val1 v, COUNT(*) c FROM Test GROUP BY val1 UNION ALL 
    SELECT val2 v, COUNT(*) FROM Test GROUP BY val2 UNION ALL 
    SELECT val3 v, COUNT(*) FROM Test GROUP BY val3 UNION ALL 
    SELECT val4 v, COUNT(*) FROM Test GROUP BY val4 UNION ALL 
    SELECT val5 v, COUNT(*) FROM Test GROUP BY val5 UNION ALL 
    SELECT val6 v, COUNT(*) FROM Test GROUP BY val6
 ) T
GROUP BY v

我的测试用例的结果是:

val occurrencies
1   5
2   5
3   11
4   5
5   5
6   4
7   1

答案 2 :(得分:3)

也许我在需求中缺少某些东西,但我认为不需要使用表值构造函数和CROSS APPLY复杂化。简单的UNION ALLGROUP BY可以胜任。

SELECT V, COUNT(*) FROM 
(
    SELECT val1 v FROM dbo.CustomerSelections
    UNION ALL
    SELECT val2 FROM dbo.CustomerSelections
    UNION ALL
    SELECT val3 FROM dbo.CustomerSelections
    UNION ALL
    SELECT val4 FROM dbo.CustomerSelections
    UNION ALL
    SELECT val5 FROM dbo.CustomerSelections
    UNION ALL
    SELECT val6 FROM dbo.CustomerSelections
) x
GROUP BY v

PS:这与其他答案非常相似,只是在性能方面稍微好一点,首先进行联合,然后再进行一次分组。