来自 Union Interaction 的 Amazon Redshift 文字

问题描述 投票:0回答:1

将两个表合并在一起并选择字符串文字(例如:SELECT 'Literal' as col1)时,会出现过滤,其中 col1 = 'Literal' 不返回任何行。


create table schema.t1 (col1 INT8, col2 varchar(max));
insert into schema.t1 (col1, col2) VALUES (1, 'A'), (2, 'B'), (3, NULL);
create table schema.t2 (col1 INT8);
insert into schema.t2 (col1) values (4);

with cte as (
select col1, coalesce(col2, 'None') "col2" from schema.t1 
UNION 
select col1, 'Literal' from schema.t2 
)
select * from cte where col2 = 'Literal'
;

很明显 col2 = 'Literal' 应该返回一行,但在运行上述代码时我看到 0 个结果。

在列周围包裹 Trim() 似乎会返回结果:

with cte as (
select col1, coalesce(col2, 'None') "col2" from schema.t1 
UNION 
select col1, 'Literal' from schema.t2 
)

select * from cte where trim(col2) = 'Literal';

省略 UNION 也会返回结果:

with cte as (
    SELECT col1, 'Literal'::text as "col2" from schema.t2
)
select * from cte where col2 = 'Literal'

我尝试将文字转换为不同类型,但仍然无法返回结果。

amazon-redshift redshift-query
1个回答
0
投票

在 Redshift Serverless 上运行查询会产生预期结果

col1,      col2
4,         Literal

您遇到的情况似乎是对 t2 表误用了 WHERE 子句。 Redshift 将 WHERE 子句下推到表扫描并使用元数据来决定是否需要数据。 看起来 Redshift 正在为 t2 执行此操作,但它不符合其元数据中的标准。 通过将trim()添加到WHERE子句,您将破坏RS测试元数据的能力,从而允许扫描t2行。 由于我无法重现您所看到的内容,因此我只能提供一些想法。

  1. 检查您的 Redshift 集群的版本是否是最新的,并且 补丁。 如果你已经过时了,那么这可能已经修复了 问题。
  2. 测试是否在联合后选择中显式命名该列 给出了所需的线索“选择 col1,‘文字’作为 t2 中的 col2”。
  3. 测试 UNION 中第一个 t2 是否会改变行为,但您会 需要明确命名 col2 作为 UNION 集合中的第一个选择 列名称。

如果您的集群是最新的并且错误应用了 WHERE 子句,您可以向 AWS 提交错误,但首先检查所有基础。

© www.soinside.com 2019 - 2024. All rights reserved.