例如我有表A和表B
a.data = {1,2,3,4,5,6} b.data = {4,5,7}
如果要在a.data或b.data中查找一个值,可以使用FIND_IN_SET(3,b.data)。 但我想知道是否在至少 b.data的所有值都在a.data中,否则如果我能找到 至少是b.data和a.data之间的交集。所以在这种情况下{4,5}。
INTERSECT(a.data,b.data)......就是这样的。我应该如何在MySQL中执行此操作?
更新
b.data {4,5,7}是一条记录的列数据,因此在b.data上加入a.data是行不通的。
table A
=======
ID DATA
1 {1,2,3,4,5,6}
2 {7,9,12}
table B
=======
ID DATA
1 {4,5,7}
2 {9,10,11,12}
答案 0 :(得分:3)
您可以使用INNER JOIN
查看Visual explaination of joins
SELECT fn_intersect_string(a.data, b.data) AS result FROM table_name;
您也可以将用户定义的函数编写为:
CREATE FUNCTION fn_intersect_string(arg_str1 VARCHAR(255), arg_str2 VARCHAR(255))
RETURNS VARCHAR(255)
BEGIN
SET arg_str1 = CONCAT(arg_str1, ",");
SET @var_result = "";
WHILE(INSTR(arg_str1, ",") > 0)
DO
SET @var_val = SUBSTRING_INDEX(arg_str1, ",", 1);
SET arg_str1 = SUBSTRING(arg_str1, INSTR(arg_str1, ",") + 1);
IF(FIND_IN_SET(@var_val, arg_str2) > 0)
THEN
SET @var_result = CONCAT(@var_result, @var_val, ",");
END IF;
END WHILE;
RETURN TRIM(BOTH "," FROM @var_result);
END;
答案 1 :(得分:1)
你从内部联接得到了交集:
SELECT a.data FROM a, b WHERE a.data = b.data
要确定b是否是a的子集,您可以执行
SELECT b.data FROM b LEFT JOIN a ON a.data = b.data WHERE a.data IS NULL
这将计算差异:来自b的所有值不包含在a中。如果它是空的,则b是a的子集。
您可以将这两种方法用作较大查询中的子查询。
答案 2 :(得分:1)
如果您的列属于SET
类型,则它会在内部存储为数字,并在适当的位置自动转换为该数字。您描述的操作对应于对这些数字的逐位逻辑运算。例如,可以使用两列值的bit-wise and来计算交集。
a.data & b.data AS intersection,
(a.data & b.data) <> 0 AS aAndBIntersect,
(a.data & b.data) == b.data AS bIsSubsetOfA
这要求两列的类型相同,因此相同的字符串对应于相同的位。要将结果转换回字符串,您可以使用ELT
,但所有组合都可能变得难看。作为替代方法,您可以将结果保存在具有相同数据类型的临时表中,将其存储为数字,然后将其作为字符串检索。