将SQL中的五列与其他五列进行比较

将SQL中的五列与其他五列进行比较,sql,sql-server-2008,tsql,search,case,Sql,Sql Server 2008,Tsql,Search,Case,我想将五列(x1-x5)与其他五列(y1-y5)进行比较,以确定它们的一致程度(以任何顺序) 对于匹配的值(在x1-x5中)数量(在五列y1-y5中的任何一列中),将获得0到5的分数 我可以把它写成一系列冗长的案例陈述,但有没有更有效的方法来实现这一点 这些值都是字符串。全文搜索在服务器上不可用 下面的代码演示了一个示例,其中n_found就是我试图创建的 DROP TABLE mytable; CREATE TABLE mytable( id INTEGER NOT NULL

我想将五列(x1-x5)与其他五列(y1-y5)进行比较,以确定它们的一致程度(以任何顺序)

对于匹配的值(在x1-x5中)数量(在五列y1-y5中的任何一列中),将获得0到5的分数

我可以把它写成一系列冗长的案例陈述,但有没有更有效的方法来实现这一点

这些值都是字符串。全文搜索在服务器上不可用

下面的代码演示了一个示例,其中n_found就是我试图创建的

DROP TABLE mytable;
CREATE TABLE mytable(
   id      INTEGER  NOT NULL PRIMARY KEY 
  ,x1      VARCHAR(1) NOT NULL
  ,x2      VARCHAR(1) NOT NULL
  ,x3      VARCHAR(1) NOT NULL
  ,x4      VARCHAR(1) NOT NULL
  ,x5      VARCHAR(1) NOT NULL
  ,y1      VARCHAR(1) NOT NULL
  ,y2      VARCHAR(1) NOT NULL
  ,y3      VARCHAR(1) NOT NULL
  ,y4      VARCHAR(1) NOT NULL
  ,y5      VARCHAR(1) NOT NULL
  ,n_found INTEGER  NOT NULL
);
INSERT INTO mytable(id,x1,x2,x3,x4,x5,y1,y2,y3,y4,y5,n_found) 
VALUES (1,'a','b','c','d','e','r','a','t','y','z',1);
INSERT INTO mytable(id,x1,x2,x3,x4,x5,y1,y2,y3,y4,y5,n_found)
VALUES (2,'e','a','b','d','c','m','o','a','b','z',2);
INSERT INTO mytable(id,x1,x2,x3,x4,x5,y1,y2,y3,y4,y5,n_found) 
VALUES (3,'a','b','c','d','e','f','g','h','i','j',0);
INSERT INTO mytable(id,x1,x2,x3,x4,x5,y1,y2,y3,y4,y5,n_found) 
VALUES (4,'a','b','c','d','e','b','e','a','c','d',5);
INSERT INTO mytable(id,x1,x2,x3,x4,x5,y1,y2,y3,y4,y5,n_found) 
VALUES (5,'a','b','c','e','d','d','b','x','y','z',2);

您可以使用
交叉应用
和表值构造函数:

SELECT *
FROM mytable
CROSS APPLY (SELECT COUNT(*)
             FROM (VALUES (x1),(x2),(x3),(x4),(x5)) AS t1(v)
             WHERE v IN (SELECT v
                         FROM (VALUES (y1),(y2),(y3),(y4),(y5)) AS t2(v))
            ) AS s(found);

输出:

╔═════════════════════════════════════════════════╗
║ id x1 x2 x3 x4 x5 y1 y2 y3 y4 y5 n_found found  ║
╠═════════════════════════════════════════════════╣
║ 1  a  b  c  d  e  r  a  t  y  z  1       1      ║
║ 2  e  a  b  d  c  m  o  a  b  z  2       2      ║
║ 3  a  b  c  d  e  f  g  h  i  j  0       0      ║
║ 4  a  b  c  d  e  b  e  a  c  d  5       5      ║
║ 5  a  b  c  e  d  d  b  x  y  z  2       2      ║
╚═════════════════════════════════════════════════╝
注:

如果要处理
NULL
,可以使用
COALESCE
与确定不存在的值交换
NULL

COALESCE(x1,'^')

编辑:


这似乎将NULL评估为同意。您可以修改它,使NULL与NULL不匹配吗

正如我之前所说,它已经在以这种方式运作

编辑2:

要处理
NULL
,还可以使用
INTERSECT(ALL)
等效项:

SELECT *
FROM mytable
CROSS APPLY (SELECT COUNT(*)
             FROM (SELECT v,
                       ROW_NUMBER() OVER(PARTITION BY v ORDER BY (SELECT 1)) AS c
                   FROM (VALUES (x1),(x2),(x3),(x4),(x5)) AS t1(v)
                   INTERSECT
                   SELECT v,
                       ROW_NUMBER() OVER(PARTITION BY v ORDER BY (SELECT 1))
                   FROM (VALUES (y1),(y2),(y3),(y4),(y5)) AS t2(v)
                  ) AS s2
            ) AS s(found)

没有那么漂亮,但可能比交叉应用选项的性能更好

SELECT *,
       CASE WHEN x1 IN (y1, y2, y3, y4, y5) THEN 1 ELSE 0 END 
       + CASE WHEN x2 IN (y1, y2, y3, y4, y5) THEN 1 ELSE 0 END 
       + CASE WHEN x3 IN (y1, y2, y3, y4, y5) THEN 1 ELSE 0 END 
       + CASE WHEN x4 IN (y1, y2, y3, y4, y5) THEN 1 ELSE 0 END 
       + CASE WHEN x5 IN (y1, y2, y3, y4, y5) THEN 1 ELSE 0 END 
FROM myTable

这似乎将NULL评估为同意。我看到你在上面提到了COALESCE,你能修改代码来说明如何在这个例子中使用COALESCE吗?我以前没有用过它。而且它不会处理空值(
NULL
:)@lad2025它不计算空值,我认为这是一个要求
SELECT *,
       CASE WHEN x1 IN (y1, y2, y3, y4, y5) THEN 1 ELSE 0 END 
       + CASE WHEN x2 IN (y1, y2, y3, y4, y5) THEN 1 ELSE 0 END 
       + CASE WHEN x3 IN (y1, y2, y3, y4, y5) THEN 1 ELSE 0 END 
       + CASE WHEN x4 IN (y1, y2, y3, y4, y5) THEN 1 ELSE 0 END 
       + CASE WHEN x5 IN (y1, y2, y3, y4, y5) THEN 1 ELSE 0 END 
FROM myTable