找到具有相同特征的元素

时间:2013-11-27 15:05:59

标签: mysql sql select relational-division

假设我有一张表,其中材料具有不同特征的对齐。材料可以具有一个或多个特征。然后我想找到某种材料类似的材料,这意味着至少有2个特征应该匹配。在这个例子中,当我与A比较时,我应该找到材料C,D应该找到B.在SQL中是否有任何解决方案?

material    | character
----------------------  
A           | 2
A           | 5
B           | 1
B           | 3
B           | 4
C           | 2
C           | 5
D           | 3
D           | 1

4 个答案:

答案 0 :(得分:3)

这是一个Entity-Attribute-Value表,搜索起来非常痛苦。 (在这种情况下,value隐含为TRUE的{​​{1}}。)

它涉及将所有内容与所有内容进行比较,对结果进行分组以及检查组是否匹配。实际上没有使用任何索引或智能。

has this attribute

这为每个具有所有的材料_b具有材料_a具有的特征 - HAVING子句将检查材料b中每个SELECT material_a.material AS material_a, material_b.material AS material_b FROM material AS material_a LEFT JOIN material AS material_b ON material_a.character = material_b.character AND material_a.material <> material_b.material GROUP BY material_a.material, material_b.material HAVING 0 = MAX(CASE WHEN material_b.character IS NULL THEN 1 ELSE 0 END) 材料的特征是否缺失。

更改为0并更改INNER JOIN将获得HAVING CLAUSE

share at least two materials

无论哪种方式,您仍然要将整个表连接到整个表,然后过滤掉故障。使用100种材料,即9,900种材料比较。想象一下,当你拥有1000种材料并进行999,000次比较时。或100万材料......

答案 1 :(得分:0)

您可以使用类似以下分组表的内容来确定具有2个以上相似特征的所有项目

SELECT
    material = t1.material
    , similarMaterial = t2.material
FROM
    tableName t1
    INNER JOIN tableName t2 ON t1.character = t2.character AND NOT(t1.material = t2.material)
GROUP BY material
HAVING 
    COUNT(*) >= 2

答案 2 :(得分:0)

这将根据材料输入为您提供结果:

SELECT b.material
FROM table1 a
INNER JOIN table1 b 
  ON a.character = b.character AND a.material <> b.material
WHERE a.material = 'A'  -- Your input
GROUP BY b.material
HAVING COUNT(*) > 1;

sqlfiddle demo

或者这样做可以给你配对:

SELECT a.material as LEFT_MATERIAL ,b.material AS RIGHT_MATERIAL
FROM table1 a
INNER JOIN table1 b ON a.character = b.character AND a.material <> b.material
GROUP BY a.material,b.material
HAVING COUNT(*) > 1;

sqlfiddle demo

答案 3 :(得分:0)

是的,你可以找到与SQL类似的所有类似材料配对:

SELECT c1.material, c2.material, COUNT(*) as characterCount
FROM charateristics c1
    CROSS JOIN charateristics c2
WHERE c1.material > c2.material AND c1.character = c2.character
GROUP BY c1.material, c2.material
HAVING characterCount >= 2;