简体   繁体   English

MYSQL在工会中选择与别名相同的列名

[英]MYSQL select same column name as alias in union not working

I have a simple MYSQL query that unions two tables: 我有一个简单的MYSQL查询,它会合并两个表:

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

I have a column called col1 in both tables and I need to select only rows that have a different value of that column so I select them as aliases. 我在两个表中都有一个名为col1的列,我只需要选择该列具有不同值的行,因此我选择它们作为别名。 When I run this query I got: 当我运行此查询时,我得到:

Unknown column 'col1B' in 'where clause'

Table1 data: 表1数据:

col1
----
test

Table2 data: 表2数据:

col1
----
test

The query should return no rows as each value in col1 in table1 is equal to each value in col1 in table2 instead it returns that col1 in table2 is unknown although I select it as an alias 该查询应该不返回任何行,因为table1中col1中的每个值都等于table2中col1中的每个值,但是它返回table2中的col1是未知的,尽管我选择了它作为别名

I think you need to look up the appropriate usage of UNION . 我认为您需要查找UNION的适当用法。 It will return all results from first query combined with all results from the second query. 它将返回第一个查询的所有结果以及第二个查询的所有结果。 This results in a single dataset, with a single column (not col1 and col2), just col1 in this case. 这将导致具有单个列的单个数据集(不是col1和col2),在这种情况下仅为col1。

Assuming you're trying to get all records in table1 that don't exist in table2, you can use NOT EXISTS : 假设您试图获取table1中所有不存在于table2中的记录,则可以使用NOT EXISTS

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

Why Error 1054 is being returned by OP query 为什么OP查询返回错误1054

The error that's being returned is because the name assigned to a column from the result of a UNION is taken from the first SELECT. 返回的错误是因为从UNION结果中分配给列的名称是从第一个SELECT获取的。

You can observe this by running a simple example: 您可以通过运行一个简单的示例来观察到这一点:

 SELECT 1 AS one 
  UNION
 SELECT 2 AS two 

The resultset returned by that query will contain a single column, the name assigned to the column will be one , the column name from the first SELECT. 该查询返回的结果集将包含一个列,分配给该列的名称将为one ,即第一个SELECT的列名称。 This explains why you are getting the error from your query. 这说明了为什么从查询中得到错误。


One way to return rows with no match 一种返回不匹配的行的方法

To return values of col1 from table1 which do not match any value in the col1 column from table2 ... 要从table1返回col1值,该值与table2col1列中的任何值都不匹配...

one option to use an anti-join pattern... 一种使用反连接模式的选项...

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

The LEFT JOIN operation returns all rows from table1, along with any "matching" rows found in table2. LEFT JOIN操作返回table1中的所有行,以及table2中找到的所有“匹配”行。 The "trick" is the predicate in the WHERE clause... any "matching" rows from table2 will have a non-NULL value in col1. “技巧”是WHERE子句中的谓词... table2中的任何“匹配”行在col1中将具有非NULL值。 So, if we exclude all of the rows where we found a match, we're left with rows from table1 that didn't have a match. 因此,如果我们排除找到匹配项的所有行,则剩下的是table1中没有匹配项的行。

If we want to get rows from table2 that don't have a "matching" row in table1 , we can do the same thing, just flipping the order of the tables. 如果我们想从table2中获取在table1没有“匹配”行的行,我们可以做同样的事情,只是翻转表的顺序。

If we combine the two sets, but only want a "distinct" list of "not matched" values, we can use the UNION set operator: 如果我们将这两个集合组合在一起,但只想要“不匹配”值的“不同”列表,则可以使用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

-- -

Finding out which table the non-matched value is from 找出不匹配值来自哪个表

Sometimes, we want to know which query returned the value; 有时,我们想知道哪个查询返回了值; we can get that by including a literal value as a discriminator in each query. 我们可以通过在每个查询中包含一个文字值作为鉴别符来实现。

    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

A different (usually less performant) approach to finding non-matching rows 查找不匹配行的另一种方法(通常性能较低)

An entirely different approach, to returning an equivalent result, would be do something like this: 返回相等结果的一种完全不同的方法将是这样的:

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

(The inline view q will be "materialized" as a derived table, so this approach can be expensive for large sets, and this approach won't take advantage of indexes on col1 to perform the matching.) One other small difference between this and the anti-join approach: this will omit a col1 value of NULL if a NULL exists in both tables. (内联视图q将被“物化”为派生表,因此这种方法对于大型集合可能会很昂贵,并且这种方法将不会利用col1上的索引来执行匹配。)反联接方法:如果两个表中都存在NULL,则它将忽略col1值NULL。 Aside from that, the resultset is equivalent. 除此之外,结果集是等效的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM