我正在使用SQL Server 2014,并且我需要一些有关硬查询的帮助。
我有下表(MyTable)。这些列名称仅用于示例。它们实际上彼此完全不同。
id int,
col1 int,
col2 int,
..
..
..
col70 int
对于每对连续列{(col1,col2),(col2_col3)...(col69_col70)},我需要计算以下内容:每个值具有的不同对的数量 - col_i是静态列,col_i + 1是另一个。每个值需要除以表中记录的总量。例如:
col1 | col2
45 | 789
56 | 345
99 | 234
45 | 789
45 | 222
89 | 678
89 | 345
45 | 789
90 | 234
12 | 567
计算:
((45, 789)+(45, 222))/10
(56, 345)/10
(99, 234)/10
(45, 789)+(45, 222)/10
(45, 789)+(45, 222)/10
(89, 678)+(89, 345)/10
(89, 678)+(89, 345)/10
((45, 789)+(45, 222))/10
(90, 234)/10
(12, 567)/10
输出:
col1_col2
0.2
0.1
0.1
0.2
0.2
0.2
0.2
0.2
0.1
0.1
第一条记录的说明: 45是静态列的值,所以现在我要检查我们可以用col2找到多少个不同的组合:
45 | 789
45 | 789
45 | 222
45 | 789
总的不同组合除以表格中的记录数量:2/10 = 0.2
此计算需要每对连续列。有什么建议?是否有一种智能的方法来自动计算它而不是为每对写一行查询?
答案 0 :(得分:0)
假设您有一个主键的示例:
create table my_table
(column_id int not null,
column1 int not null,
column2 int not null);
insert into my_table
(column_id, column1, column2)
values
(1, 45,789),
(2, 56,345),
(3, 99,234),
(4, 45,789),
(5, 45,222),
(6, 89,678),
(7, 89,345),
(8, 45,789),
(9, 90,234),
(10, 12,567);
declare @column_a as nvarchar(100) = N'column1';
declare @column_b as nvarchar(100) = N'column2';
declare @result_column as nvarchar(100) = N'column1_2';
declare @sql_string as nvarchar(4000)
set @sql_string =
'select a.column_id,
1.0 * count( distinct b.' + @column_b + ') / (count(a.' + @column_a + ') over ()) as ' + @result_column
+ ' from my_table a
inner join my_table b
on a.' + @column_a + ' = b.' + @column_a +
' group by a.column_id, a.' + @column_a +
' order by a.column_id';
-- print @sql_string;
execute(@sql_string);
如果没有主键,您可以使用rownumber()函数创建标识符,但结果顺序会发生变化。 print命令可用于检查动态sql字符串,此处已注释掉。
将动态SQL放入存储过程:
create procedure column_freq @column_a nvarchar(100), @column_b nvarchar(100), @result_column nvarchar(100)
as
begin
declare @sql_string as nvarchar(4000);
set @sql_string =
'select a.column_id,
1.0 * count( distinct b.' + @column_b + ') / (count(a.' + @column_a + ') over ()) as ' + @result_column
+ ' from my_table a
inner join my_table b
on a.' + @column_a + ' = b.' + @column_a +
' group by a.column_id, a.' + @column_a +
' order by a.column_id';
execute(@sql_string);
end;
go
exec column_freq N'column1', N'column2', N'column1_2';
go