我想比较五列(x1-x5)和另外五列(y1-y5),以确定它们达成一致的程度(以任何顺序)。
对于匹配的值(在x1-x5中)(在五列y1-y5中的任何一列中),奖励从0到5的分数。
我可以把它写成一系列CASE WHEN语句,但有没有更有效的方法来实现呢?
值都是字符串。服务器上没有全文搜索功能。
下面的代码说明了一个例子,其中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);
答案 0 :(得分:2)
您可以使用CROSS APPLY
和表值构造函数:
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);
的 LiveDemo
强>
输出:
╔═════════════════════════════════════════════════╗
║ 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 ║
╚═════════════════════════════════════════════════╝
注意:
如果您想处理NULLs
,可以使用COALESCE
与您确定不存在的值交换NULL
:
COALESCE(x1,'^')
的 LiveDemo2
强>
修改强>
这似乎评估NULL同意。你可以修改它,以便NULL与NULL相比不匹配吗?
正如我之前所说,它已经在那样工作了。
的 LiveDemo3
强>
╔════╦════╦════╦════╦════╦══════╦════╦════╦════╦════╦══════╦═════════╦═══════╗
║ id ║ x1 ║ x2 ║ x3 ║ x4 ║ x5 ║ y1 ║ y2 ║ y3 ║ y4 ║ y5 ║ n_found ║ found ║
╠════╬════╬════╬════╬════╬══════╬════╬════╬════╬════╬══════╬═════════╬═══════╣
║ 6 ║ a ║ a ║ c ║ e ║ NULL ║ o ║ y ║ x ║ y ║ NULL ║ 0 ║ 0 ║
╚════╩════╩════╩════╩════╩══════╩════╩════╩════╩════╩══════╩═════════╩═══════╝
编辑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)
的 LiveDemo4
强>
答案 1 :(得分:0)
不是很漂亮,但可能比交叉应用选项更好。
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
的 Demo
强>