2014-09-23 72 views
0

我有一个简单的MySQL查询,工会两个表:MYSQL选择相同的列名作为工会别名不工作

SELECT * FROM (
    SELECT col1 AS col1A FROM table1 
    UNION 
    SELECT col1 AS col1B FROM table2 
) AS t WHERE col1A <> col1B 

我有一个叫这两个表中col1列,我需要选择只有那些行该列的不同值,所以我选择它们作为别名。当我运行此查询我:

Unknown column 'col1B' in 'where clause' 

表1数据:

col1 
---- 
test 

表2数据:

col1 
---- 
test 

查询应在表1返回col1中没有任何行,因为每个值等于到表2中的col1中的每个值,而是返回表2中的col1未知,尽管我选择它作为别名

+0

你想输出什么?如果你只执行'UNION'内部查询,你会发现这里出错了。 'UNION'只返回一列,它被称为'col1A'(虽然它也包含你所谓的'col1B'的值) – 2014-09-23 23:50:42

+0

如果你从每个表格中发布一小段样本的行以及你希望的输出为了从样本中获得,我们可以帮助您解决这个问题。 – 2014-09-23 23:51:06

+0

为什么不具体和使用:'WHERE table1.col1 <> table2.col1' – 2014-09-23 23:58:33

回答

3

为什么错误1054是由OP查询返回

返回的错误是因为从UNION结果中分配给列的名称是从第一个SELECT中获取的。

SELECT 1 AS one 
    UNION 
SELECT 2 AS two 

由该查询返回包含单个列的结果集,分配给列名称将是one,从第一选择列名:

您可以通过运行一个简单的例子观察这。这解释了为什么你从查询中收到错误。


一种方式与不匹配

table1不匹配,从table2col1列的任何值返回的col1值返回行...

一个选项使用反接合模式...

SELECT t1.col1 
     FROM table1 t1 
     LEFT 
     JOIN table2 t2 
     ON t2.col1 = t1.col1 
    WHERE t2.col1 IS NULL 

Th e LEFT JOIN操作返回全部行以及表2中找到的任何“匹配”行。 “技巧”是WHERE子句中的谓词...来自table2的任何“匹配”行在col1中将具有非空值。因此,如果我们排除找到匹配的所有行,则我们剩下来自table1的没有匹配的行。

如果我们想从table2中得到table1中没有“匹配”行的行,我们可以做同样的事情,只是翻转表的顺序。

如果我们结合了两套,但只想要“不匹配”值的“独特”列表中,我们可以使用UNION集合运算符:

SELECT t1.col1 
     FROM table1 t1 
     LEFT 
     JOIN table2 t2 
     ON t2.col1 = t1.col1 
    WHERE t2.col1 IS NULL 
    UNION 
    SELECT s2.col1 
     FROM table2 s2 
     LEFT 
     JOIN table1 s1 
     ON s1.col1 = s2.col1 
    WHERE s1.col1 IS NULL 

-

找出哪个表的不匹配值是从

有时候,我们想知道哪个查询返回的值;我们可以通过在每个查询中包含一个字面值作为鉴别器。

SELECT 'table1' AS src 
     , t1.col1 
     FROM table1 t1 
     LEFT 
     JOIN table2 t2 
     ON t2.col1 = t1.col1 
    WHERE t2.col1 IS NULL 
    UNION 
    SELECT 'table2' AS src 
     , s2.col1 
     FROM table2 s2 
     LEFT 
     JOIN table1 s1 
     ON s1.col1 = s2.col1 
    WHERE s1.col1 IS NULL 
    ORDER BY 2 

不同的(通常不高性能)的方法来找到不匹配行

一种完全不同的方法,以返回一个等效的结果,将是这样做的:

SELECT q.col1 
    FROM (SELECT 't1' AS src, t1.col1 FROM table1 t1 
      UNION 
     SELECT 't2' AS src, t2.col1 FROM table2 t2 
     ) q 
GROUP BY q.col1 
HAVING COUNT(DISTINCT q.src) < 2 
ORDER BY q.col1 

(内联视图q将作为派生表“物化”,因此此方法可以是ex这种方法不会利用col1上的索引来执行匹配。)与反连接方法之间的另一个小差异是:如果两个NULL都存在,则会省略col1的NULL值表。除此之外,结果集是等价的。

+0

谢谢,但我已经知道左连接:)我想从两个表的结果被返回到单独的行,所以加入将无法在我的情况下工作,所以我必须工会 – 2014-09-24 00:29:40

+0

@MichaelSamuel:我错过了你的观点制造。我提供的查询返回单独行上的每个“不匹配”值。从反连接返回的行都不会有“两行”的值。你对“我必须结合”的理由是愚蠢的。 (显然,你可以在任何你想要的查询中自由使用'UNION',你应该,因为你“必须结合”。) – spencer7593 2014-09-24 00:43:43

+0

@MichaelSamuel - 不,你不会......工会不会完成你正在努力去做。 – Twelfth 2014-09-24 00:43:49

6

我认为你需要查找UNION的适当用法。它将返回第一个查询的所有结果以及第二个查询的所有结果。这导致了一个数据集,只有一列(不是col1和col2),在这种情况下只有col1。

假设你正在试图获得在表1中的所有记录中不存在表2,你可以使用NOT EXISTS

SELECT col1 
FROM table1 t1 
WHERE NOT EXISTS (
    SELECT 1 
    FROM table2 t2 
    WHERE t1.col1 = t2.col1 
    ) 
+0

不,我不只是想要存在于其中的行而不存在于其中。这只是简化以查明问题。我想多个条件,这是其中之一 – 2014-09-24 00:19:00

+0

@MichaelSamuel - 你真的需要更新你的问题来解释你想要完成的事情。显然,我们在理解你的需求方面遇到了很多麻烦。尝试使用示例数据(每个表格多于一行)和期望的结果。也许更好,建立一个sqlfiddle.com来展示你有问题的地方!这看起来似乎回答你的问题,因为它目前正在编写。 – sgeddes 2014-09-24 00:24:01

+0

我的要求很简单,我需要了解我发布的语法有什么问题。这与使用无关。我想知道发布的代码有什么问题。为什么mysql假定这个列是未知的 – 2014-09-24 00:42:49