【问题标题】:Using concat in comparison returns everything在比较中使用 concat 会返回所有内容
【发布时间】:2021-09-19 07:26:57
【问题描述】:

在一个视图中,我有一列是一个表的 2 列的串联(下面的 sqlfiddle 示例)。

在查询此视图 (v1) 时,我在同一视图 (v2) 上使用了子查询。 如果两个视图之间的链接是单列 (id_part_2),则行为是预期的(1 个结果)。

但是,如果链接是连接列 ('id'),而子查询本身返回单个结果,整个查询不会应用 where 条件(返回每一行)。

http://sqlfiddle.com./#!9/6c2138/1

问题来自两列的CONCAT(如果只有CONCAT('foo', id_part_2),则没有问题)。

我知道可以在没有子查询的情况下编写查询,我知道 CONCAT 只能在最终结果中完成。但是,编写查询的方式并不完全在我的控制范围内。我更想知道为什么会出现这种行为以及是否有办法避免这种行为。

旁注,我无法在我自己的数据库(在远程服务器上见证)上重现此行为,这让我相信数据库本身可以被编辑。

结构(在 MySQL 5.6 中):

 CREATE TABLE `table_1` (
  `id_part_1` varchar(255) NOT NULL,
  `id_part_2` varchar(255) NOT NULL,
  `search` varchar(255) NOT NULL,
  PRIMARY KEY (`id_part_1`,`id_part_2`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE 
    ALGORITHM = UNDEFINED 
    SQL SECURITY INVOKER
VIEW `view_1` AS
    SELECT 
        CONCAT(`table_1`.`id_part_1`,
        `table_1`.`id_part_2`) AS `id`,
        
    `table_1`.`id_part_2` AS `id_part_2`,
    `table_1`.`search` AS `search`
FROM `table_1`;
        
insert into table_1 values ('A', '1', 'foo1');
insert into table_1 values ('A', '2', 'foo2');
insert into table_1 values ('A', '3', 'foo3');
insert into table_1 values ('B', '4', 'foo4');
insert into table_1 values ('B', '5', 'foo5');
insert into table_1 values ('B', '6', 'foo6');

查询成功:

SELECT v1.id AS id_1
FROM view_1 v1 
WHERE v1.id_part_2 IN (
    SELECT v2.id_part_2
    FROM view_1 v2 
    WHERE v2.search = 'foo2') 
;

查询 NOK:

SELECT v1.id AS id_1
FROM view_1 v1 
WHERE v1.id IN (
    SELECT v2.id
    FROM view_1 v2 
    WHERE v2.search = 'foo2') 
;

【问题讨论】:

    标签: mysql view subquery concatenation


    【解决方案1】:

    这只是该版本中的一个错误

    在英国的 dbfiddle 中,此作品见示例

    还有https://www.db-fiddle.com/f/exfkgCJpH9X4ped4S2PGpj/1

    CREATE TABLE `table_1` (
      `id_part_1` varchar(255) NOT NULL,
      `id_part_2` varchar(255) NOT NULL,
      `search` varchar(255) NOT NULL,
      PRIMARY KEY (`id_part_1`,`id_part_2`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    CREATE 
        ALGORITHM = UNDEFINED 
        SQL SECURITY INVOKER
    VIEW `view_1` AS
        SELECT 
            CONCAT(`table_1`.`id_part_1`,
                        `table_1`.`id_part_2`) AS `id`,
                
            `table_1`.`id_part_2` AS `id_part_2`,
            `table_1`.`search` AS `search`
        FROM `table_1`;
            
    insert into table_1 values ('A', '1', 'foo1');
    insert into table_1 values ('A', '2', 'foo2');
    insert into table_1 values ('A', '3', 'foo3');
    insert into table_1 values ('B', '4', 'foo4');
    insert into table_1 values ('B', '5', 'foo5');
    insert into table_1 values ('B', '6', 'foo6');
    
    SELECT v1.id AS id_1
    FROM view_1 v1 
    WHERE v1.id_part_2 IN (
        SELECT v2.id_part_2
        FROM view_1 v2 
        WHERE v2.search = 'foo2') 
    ;
    
    SELECT v1.id AS id_1
    FROM view_1 v1 
    WHERE v1.id IN (
        SELECT v2.id
        FROM view_1 v2 
        WHERE v2.search = 'foo2') 
    ;
    
    | id_1 | | :--- | | A2 | | id_1 | | :--- | | A2 |

    dbfiddle here 版本

    【讨论】:

      猜你喜欢
      • 2019-07-08
      • 2010-12-22
      • 1970-01-01
      • 2011-11-24
      • 2012-06-29
      • 1970-01-01
      • 1970-01-01
      • 2015-09-18
      • 2012-05-09
      相关资源
      最近更新 更多