Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 查找行中任意两个字段是否相等的查询?_Sql_Sql Server 2008 - Fatal编程技术网

Sql 查找行中任意两个字段是否相等的查询?

Sql 查找行中任意两个字段是否相等的查询?,sql,sql-server-2008,Sql,Sql Server 2008,我必须维护一个设计非常糟糕的可怕的遗留数据库。所有表都有100多列,其中一个有650列。数据库是非常非规范化的,我发现通常相同的数据在同一行的几列中表示 例如,以下是其中一个表的列示例: [MEMBERADDRESS] [varchar](331) NULL, [DISPLAYADDRESS] [varchar](max) NULL, [MEMBERINLINEADDRESS] [varchar](max) NULL, [DISPLAYINLINEADDRESS] [varchar](250)

我必须维护一个设计非常糟糕的可怕的遗留数据库。所有表都有100多列,其中一个有650列。数据库是非常非规范化的,我发现通常相同的数据在同一行的几列中表示

例如,以下是其中一个表的列示例:

[MEMBERADDRESS] [varchar](331) NULL,
[DISPLAYADDRESS] [varchar](max) NULL,

[MEMBERINLINEADDRESS] [varchar](max) NULL,
[DISPLAYINLINEADDRESS] [varchar](250) NULL,

[__HISTISDN] [varchar](25) NULL,
[HISTISDN] [varchar](25) NULL,
[MYDIRECTISDN] [varchar](25) NULL,
[MYISDN] [varchar](25) NULL,

[__HISTALT_PHONE] [varchar](25) NULL,
[HISTALT_PHONE] [varchar](25) NULL,
原来
MEMBERADDRESS
DISPLAYADDRESS
对于表中的所有行都具有相同的值。我在这里展示的其他字段集群也是如此

手动识别所有此类病例将非常困难且耗时。是否可以创建一个查询来标识表中的每一行中两个字段是否具有相同的值


如果没有,是否有任何现有工具可以帮助我识别此类问题?

我认为有两种方法可以简化此查询:

  • 编写一个生成查询的脚本-向脚本提供表名和可疑列,并让脚本生成一个检查每对列是否相等的查询。这是在像您这样的情况下实现的最快方法
  • 编写一个“规范化”数据的查询,并对其进行搜索-将查询自身加入,然后过滤掉重复的查询
下面是第二种方法的快速示例:

SELECT id, name, val FROM (
    SELECT id, MEMBERADDRESS as val,'MEMBERADDRESS' as name FROM MyTable
    UNION ALL
    SELECT id, DISPLAYADDRESS as val,'DISPLAYADDRESS' as name FROM MyTable
    UNION ALL
    SELECT id, MEMBERINLINEADDRESS as val,'MEMBERINLINEADDRESS' as name FROM MyTable
    UNION ALL
    ...
) first
JOIN (
    SELECT id, MEMBERADDRESS as val,'MEMBERADDRESS' as name FROM MyTable
    UNION ALL
    SELECT id, DISPLAYADDRESS as val,'DISPLAYADDRESS' as name FROM MyTable
    UNION ALL
    SELECT id, MEMBERINLINEADDRESS as val,'MEMBERINLINEADDRESS' as name FROM MyTable
    UNION ALL
    ...
) second ON first.id=second.id AND first.value=second.value

对于100列,需要大量的手工工作(至少不像第一种方法那样,它不会像
N^2
那样增长,但仍然需要大量的手工输入)。您最好使用一个小脚本生成与
UNION ALL
连接的选择。

以下方法使用
unpivot
创建三元组。它做了一些假设:值不是空的;每行有一个id;和列具有兼容的类型

select t.which, t2.which 
from (select id, which, value
      from MEMBERADDRESS
      unpivot (value for which in (<list of columns here>)) up
     ) t full outer join
     (select id, which, value
      from MEMBERADDRESS
      unpivot (value for which in (<list of columns here>)) up
     ) t2
     on t.id = t2.id and t.which <> t2.which
group by t.which, t2.which
having sum(case when t.value = t2.value then 1 else 0 end) = count(*)

获取更完整的信息。

最简单的方法是从信息架构表中构建动态SQL语句。但市场上可能也有用于此的工具…@DominicGoulet这是我现在正在研究的,但我认为这将非常缓慢。也许这是唯一的解决办法。谢谢你的回答。我正在尝试您的查询,但它告诉我“up”附近的语法不正确。。我将列列表放在您指定的位置,但我无法确定在何处指定所有这些操作的表!你能澄清一下用法吗?我的SQL知识对于这些更深奥的方法来说不是很好。@oliver。在
up
之前,我删除了第二个结束部分。谢谢,我想我会试试你的脚本解决方案-至少对于一些较小的表。
select t.which, t2.which, sum(case when t.value = t2.value then 1 else 0 end) as Nummatchs,
       count(*) as NumRows