交叉标记具有多个 ID 的 Microsoft SQL Server 表 - 每个变量 ID 的 2x2 网格

问题描述 投票:0回答:2

我在 Microsoft SQL Server 中有一个表,如下所示:

主键 IDx IDy IDz 计数
123450 0 0 0 0
123450 0 0 1 1
123450 0 0 2 0
123450 0 0 3 5
123450 1 0 0 4
123450 1 0 1 3
123450 1 0 2 8
123450 1 0 3 0
123450 0 1 0 5
123450 0 1 1 6
123450 0 1 2 0
123450 0 1 3 0
123450 1 1 0 6
123450 1 1 1 2
123450 1 1 2 3
123450 1 1 3 1
123450 0 2 0 4
123450 0 2 1 5
123450 0 2 2 0
123450 0 2 3 7
123450 1 2 0 9
123450 1 2 1 9
123450 1 2 2 2
123450 1 2 3 5
123451 ... ... ... ...
  • ID1 可以是 0 或 1。
  • ID2 可以是 0、1 或 2。
  • ID3 可以是 0、1、2 或 3。

我想像下表一样取消透视:

主键 ID_Type 计数
123450 IDx_0_IDy_0 6
123450 IDx_1_IDy_0 12
123450 IDx_0_IDy_1 11
123450 IDx_1_IDy_1 12
123450 IDx_0_IDy_2 16
123450 IDx_1_IDy_2 25
123450 IDx_0_IDz_0 20

如您所见,我喜欢看到的是我想在每个 ID 的不同值之间创建一个交叉表。事实上,在 ID_Type 列中,每当看到像 IDx_a_IDy_b 这样 Main_Key = ZZZ 的 ID 时,计数变量将是具有 Main_Key = ZZZ 和 IDx = a 且 IDy = b(a每两个 ID 之间的 2x2 网格)。

我已经通过首先根据许多“CASE”条件创建网格来解决这个问题:

select
     main_key,
     sum(case when IDx = 0 and IDy = 0 then count else 0 end) as IDx_0_IDy_0,
     sum(case when IDx = 1 and IDy = 0 then count else 0 end) as IDx_1_IDy_0,
     sum(case when IDx = 0 and IDy = 1 then count else 0 end) as IDx_0_IDy_1,
from
     table
group by
     main_key

然后使用“UNPIVOT”方法或“UNION ALL”方法取消透视。但是,这种方法需要很长时间,尤其是在我的表中将有大约 1500 万条记录的情况下。 SQL中是否有任何内置方法可以做这样的事情?或者使这个查询更快?非常感谢:)

sql sql-server pivot-table unpivot union-all
2个回答
0
投票

看起来你只需要按

IDx
IDy

分组
select
  main_key,
  IDx,
  IDy,
  SUM(count)
FROM YourTable t
GROUP BY
  main_key,
  IDx,
  IDy;

db<>小提琴

为了使其表现良好,您需要以下索引,这也将改进您的原始查询

  INDEX IX CLUSTERED (Main_key, IDx, IDy)
-- alternatively
  INDEX IX NONCLUSTERED (Main_key, IDx, IDy) INCLUDE (count)

0
投票

您可以尝试按 idx 和 idy 进行查询,并将结果与

UNION ALL
放在一起。

select main_key, 'IDx_0_IDy_0' as id_type, count(*)
from mytable
where idx = 0 and idy = 0
group by main_key
union all
select main_key, 'IDx_1_IDy_0' as id_type, count(*)
from mytable
where idx = 1 and idy = 0
group by main_key
union all
...

只有在索引合适的情况下才有机会快速运行。这个可能会做:

create index idx on mytable (idx, idy, main_key);

但是,每个查询一个索引的机会要好得多:

create index idx00 on mytable (main_key) where idx = 0 and idy = 0;
create index idx10 on mytable (main_key) where idx = 1 and idy = 0;
...

您甚至可以在

INCLUDE
子句中包含计数。然后,创建集群索引还是非集群索引可能会有所不同,但不是 SQL Server 人员,这是我不知道的事情。

© www.soinside.com 2019 - 2024. All rights reserved.