计算SQL表中行之间的差异

时间:2020-01-13 12:12:06

标签: sql sql-server

我有以下SQL Server表:

  Group  |  SubGroup  |  Value
----------------------------------
  D934   |     A      |   100
  D934   |     A      |   101
  D934   |     A      |   102
  D934   |     B      |   100
  D934   |     B      |   103
  D934   |     C      |   102
  D934   |     C      |   105
  D955   |     A      |   100
  D955   |     A      |   103
  D955   |     B      |   101
  D955   |     B      |   102
  D955   |     B      |   103
  D955   |     D      |   101
  D955   |     D      |   103

我想计算每个分组的子分组A和B,A和C ...之间的差异。 例如,对于D934,A和B具有3个差异(值101、102和103)。

结果:

  Group  |  SubGroup  |  SubGroup To Compare  |  Differences
-------------------------------------------------------------
  D934   |     A      |          A            |      0
  D934   |     A      |          B            |      3
  D934   |     A      |          C            |      3
  D934   |     B      |          A            |      3
  D934   |     B      |          B            |      0
  D934   |     B      |          C            |      4
  D934   |     C      |          A            |      3
  D934   |     C      |          B            |      4
  D934   |     C      |          C            |      0
  D955   |     A      |          A            |      0
  D955   |     A      |          B            |      3
  D955   |     A      |          D            |      2
  D955   |     B      |          A            |      3
  D955   |     B      |          B            |      0
  D955   |     B      |          D            |      1
  D955   |     D      |          A            |      2
  D955   |     D      |          B            |      1
  D955   |     D      |          D            |      0

我想在单个SQL查询中实现结果表。你能建议吗?

1 个答案:

答案 0 :(得分:1)

这是一个复杂的问题。您可以使用自连接和计数进行此计算。关键计数是:

  • 两组之间有多少个值匹配。
  • 每个组中有多少个唯一值。

然后,差异就是每个组中唯一值的总和减去第一个值两次-这是因为匹配的值被计算两次。

因此,查询为:

select t1.grp, t1.subgrp, t2.subgrp,
       (case when t1.subgrp = t2.subgrp then 0
             else count(distinct t1.val) +
                  count(distinct t2.val) -
                  2 * sum(case when t1.val = t2.val then 1 else 0 end)
        end) as diff
from t t1 join
     t t2
     on t1.grp = t2.grp 
group by t1.grp, t1.subgrp, t2.subgrp
order by 1, 2, 3;

Here是db <>小提琴。