- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我从外部来源接收原始数据文件,需要对其进行分析。我将文件加载到一个表中并将字段设置为 varchars,然后运行一个复杂的 SQL 脚本来进行一些自动分析。我一直试图解决的一个问题是:如何判断一列数据是否与同一表中的 1 个或多个其他列重复?
我的目标是为每一列创建一个散列、校验和或类似的东西,以按照它们出现的顺序查看每行中的列值。我有动态 SQL,它根据 INFORMATION_SCHEMA.COLUMNS 中列出的字段循环遍历每个字段(不同的表将具有可变数量的列),因此无需担心如何完成该部分。
我一整天都在研究这个问题,但似乎找不到任何合理的方法来散列字段的每一行。 Google 和 StackOverflow 搜索返回如何对数据行执行各种操作,但我找不到太多关于如何在字段上垂直执行相同操作的信息。
因此,我考虑了 2 种可能性并遇到了 2 个障碍:
第二个看起来很有希望,但没有像我希望的那样工作......
declare @t1 table
(col_1 varchar(5)
, col_2 varchar(5)
, col_3 varchar(5));
insert into @t1
values ('ABC', 'ABC', 'ABC')
, ('ABC', 'ABC', 'BCD')
, ('BCD', 'BCD', NULL)
, (NULL, NULL, 'ABC');
select * from @t1;
select cs_1 = CHECKSUM(col_1)
, cs_2 = CHECKSUM(col_2)
, cs_3 = CHECKSUM(col_3)
from @t1;
select csa_1 = CHECKSUM_AGG(CHECKSUM([col_1]))
, csa_2 = CHECKSUM_AGG(CHECKSUM([col_2]))
, csa_3 = CHECKSUM_AGG(CHECKSUM([col_3]))
from @t1;
在最后一个结果集中,所有 3 列都返回相同的值:2147449198。
期望的结果:我的目标是让一些代码在其中 csa_1 和 csa_2 带回相同的值,而 csa_3 带回不同的值,表明它是自己独特的集合。
最佳答案
您可以用这种方式比较每个列的组合,而不是使用散列:
select case when count(case when column1 = column2 then 1 else null end) = count(1) then 1 else 0 end Column1EqualsColumn2
, case when count(case when column1 = column3 then 1 else null end) = count(1) then 1 else 0 end Column1EqualsColumn3
, case when count(case when column1 = column4 then 1 else null end) = count(1) then 1 else 0 end Column1EqualsColumn4
, case when count(case when column1 = column5 then 1 else null end) = count(1) then 1 else 0 end Column1EqualsColumn5
, case when count(case when column2 = column3 then 1 else null end) = count(1) then 1 else 0 end Column2EqualsColumn3
, case when count(case when column2 = column4 then 1 else null end) = count(1) then 1 else 0 end Column2EqualsColumn4
, case when count(case when column2 = column5 then 1 else null end) = count(1) then 1 else 0 end Column2EqualsColumn5
, case when count(case when column3 = column4 then 1 else null end) = count(1) then 1 else 0 end Column3EqualsColumn4
, case when count(case when column3 = column5 then 1 else null end) = count(1) then 1 else 0 end Column3EqualsColumn5
, case when count(case when column4 = column5 then 1 else null end) = count(1) then 1 else 0 end Column4EqualsColumn5
from myData a
这是设置代码:
create table myData
(
id integer not null identity(1,1)
, column1 nvarchar (32)
, column2 nvarchar (32)
, column3 nvarchar (32)
, column4 nvarchar (32)
, column5 nvarchar (32)
)
insert myData (column1, column2, column3, column4, column5)
values ('hello', 'hello', 'no', 'match', 'match')
,('world', 'world', 'world', 'world', 'world')
,('repeat', 'repeat', 'repeat', 'repeat', 'repeat')
,('me', 'me', 'me', 'me', 'me')
这是强制性的 SQL Fiddle .
此外,为了避免您必须编写此代码,这里有一些代码可以生成上述内容。此版本还将包含处理两列的值为空的情况的逻辑:
declare @tableName sysname = 'myData'
, @sql nvarchar(max)
;with cte as (
select name, row_number() over (order by column_id) r
from sys.columns
where object_id = object_id(@tableName, 'U') --filter on our table
and name not in ('id') --only process for the columns we're interested in
)
select @sql = coalesce(@sql + char(10) + ', ', 'select') + ' case when count(case when ' + quotename(a.name) + ' = ' + quotename(b.name) + ' or (' + quotename(a.name) + ' is null and ' + quotename(b.name) + ' is null) then 1 else null end) = count(1) then 1 else 0 end ' + quotename(a.name + '_' + b.name)
from cte a
inner join cte b
on b.r > a.r
order by a.r, b.r
set @sql = @sql + char(10) + 'from ' + quotename(@tableName)
print @sql
注意:这并不是说您应该将其作为动态 SQL 运行;相反,您可以使用它来生成代码(除非您需要支持列的数量或名称在运行时可能会发生变化的情况,在这种情况下您显然需要动态选项)。
关于sql - 如何在 SQL Server 中散列表的列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50072216/
我是一名优秀的程序员,十分优秀!