2016-02-18 45 views
1

我有一个名称为几个的表,我希望在搜索第二个表上的等同项之前从这些名称中删除一些后缀。使用MySql用户变量的差异

为了做到这一点,我决定将我希望修改的列存储在一个变量中,并在我的第二个表中修改所述变量进行比较。修改之前

查询:

SELECT T1.id, T1.name 
FROM Table1 T1 
WHERE T1.id IN (
    SELECT T2.id 
    FROM Table2 T2 
    WHERE T2.textBlock like concat('%', T1.name, '%') 
) 

与用户变量新建查询(用于测试,在@newname所有的操作被拆除)

SELECT *, @newName:=T1.name 
FROM Table1 T1 
WHERE T1.id IN (
    SELECT T2.id 
    FROM Table2 T2 
    WHERE T2.textBlock like concat('%', @newName, '%') 
) 

第一个查询返回590个结果。即使没有对变量进行修改,第二个查询也会返回225个结果。什么可能导致结果的差异?

+0

两个查询都不应该工作,因为'%'应该导致解析错误。相关的子查询是正确的方法;没有理由认为一个变量在这种情况下会起作用。 –

回答

0

通常,SELECT子句中的字段在WHERE;很可能在变量中使用的值就是执行查询之前发生的任何事情。

我是用户/会话变量的忠实粉丝,但跨子句使用它们非常不可靠,也是他们声誉如此糟糕的最大原因。

---你能做些什么---

我不是相关子查询的一个巨大的风扇;他们有他们的目的,而当他们真正需要的时候,很少有人可以相当优雅,但是在我的经验中他们很少需要。你是像这样的东西更好...

SELECT DISTINCT T1.id, T1.name 
FROM (SELECT id, name, X AS trimmedName FROM Table1) AS T1 
INNER JOIN Table2 AS T2 
    ON T1.id = T2.id 
    AND T2.textBlock LIKE concat('%', T1.trimmedName, '%') 
; 

LIKE与一家领先的通配符仍然会与性能的障碍,虽然为您呈现;但希望id平等条件将否定这个问题。

---或者--- 我还没有使用过它们,但我发现人们使用EXISTS报告了良好的结果。像这样的东西....

SELECT T1.id, T1.name 
FROM Table1 T1 
WHERE EXISTS (
    SELECT * 
    FROM Table2 T2 
    WHERE T2.id = t1.id AND T2.textBlock like concat('%', T1.name, '%') 
) 
+0

感谢您澄清@Uueerdo。在这种情况下,你是否会对如何在子查询的T1.name字段上执行必要的修改提出建议? –

+0

@ScribeAssistant查看编辑 – Uueerdo

+0

你的建议解决了这个问题。我只是直接在子查询中添加所有字符串操作。不是最优雅的方式,但完全有效。 –

0

让我假设你的查询是:

SELECT *, @newName:=T1.name 
FROM Table1 T1 
WHERE T1.id IN (SELECT T2.id 
       FROM Table2 T2 
       WHERE T2.textBlock like concat('%', @newName, '%') 
       ); 

我希望它可以有很莫名其妙的结果。在另一个表达式中分配的变量在另一个表达式中引用时没有特定的值你不知道SQL优化器可能在做什么。在某些版本的MySQL中,可以针对每一行评估子查询;在更新的版本中,它可能会被评估一次。

无论如何,第一种方法是编写查询的正确方法。你为什么要不必要地使用变量?

+0

我使用了这个变量,因为我需要使用几个'@newName:= SUBSTRING_INDEX(@newName,'some string',1)'来移除字符串中不需要的部分(15个可能不需要的后缀,更具体)。 –