将SQL中的五列与其他五列进行比较
我想将五列(x1-x5)与其他五列(y1-y5)进行比较,以确定它们的一致程度(以任何顺序) 对于匹配的值(在x1-x5中)数量(在五列y1-y5中的任何一列中),将获得0到5的分数 我可以把它写成一系列冗长的案例陈述,但有没有更有效的方法来实现这一点 这些值都是字符串。全文搜索在服务器上不可用 下面的代码演示了一个示例,其中n_found就是我试图创建的将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
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