我在 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 | ... | ... | ... | ... |
我想像下表一样取消透视:
主键 | 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中是否有任何内置方法可以做这样的事情?或者使这个查询更快?非常感谢:)
看起来你只需要按
IDx
和IDy
分组
select
main_key,
IDx,
IDy,
SUM(count)
FROM YourTable t
GROUP BY
main_key,
IDx,
IDy;
为了使其表现良好,您需要以下索引,这也将改进您的原始查询
INDEX IX CLUSTERED (Main_key, IDx, IDy)
-- alternatively
INDEX IX NONCLUSTERED (Main_key, IDx, IDy) INCLUDE (count)
您可以尝试按 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 人员,这是我不知道的事情。