Oracle Left Join 导致单行子查询返回多行错误
Posted
技术标签:
【中文标题】Oracle Left Join 导致单行子查询返回多行错误【英文标题】:Oracle Left Join causing single-row subquery returns more than one row error 【发布时间】:2020-09-04 14:54:49 【问题描述】:不知道为什么这段代码不起作用——似乎是一个相对容易的连接。
select *
FROM VIEW_DB.VIEW1 VC0
LEFT OUTER JOIN VIEW_DB.VIEW2 VC1
ON TRIM(VC0.STRING_DATE) = TO_CHAR(VC1.CALENDAR_DAY, 'MM/DD/YYYY')
在示例中 VC0.STRING_DATE 是一个包含 varchar 数据的字段,2020 年 1 月 1 日的示例将是:“01/01/2020”(添加引号以显示空白)。
日历日是一个日期字段。
目标是在左外连接完整的情况下连接字符串日期到日期字段。使用 INNER 加入,这可以正常工作。
附加说明
VIEW1 -- 只是一个临时表的 1:1 视图。 STRING_DATE 存储为 VARCHAR(100)。在这件事上我别无选择。我们希望通过更好的 ETL 映射来消除这个问题,但目前这是我们坚持的问题。
VIEW2 -- CAL_DT 是一个 DATE 列。制作者:TRUNC(to_date('2020/01/01', 'yyyy/mm/dd') -1 + N.n) as CAL_DT
【问题讨论】:
向我们展示视图定义... 我不明白这会如何引发单行子查询返回多行错误。 关心共享列类型,如果它们是 VARCHAR2,格式?我闻到可能需要一两个 trunc()。 查询看起来没问题。错误必须在其中一个视图中。 @jarlh 我添加了更多详细信息。 【参考方案1】:转换值,但仅在一侧:
SELECT *
FROM VIEW_DB.VIEW1 VC0 LEFT OUTER JOIN
VIEW_DB.VIEW2 VC1
ON TO_DATE(VC0.STRING_DATE, 'MMM DD YYYY') = VC1.CALENDAR_DAY;
当然,这可能会产生类型转换错误。这是一件好事。您应该学习如何使用正确的数据类型存储值。而且字符串不是日期的正确数据类型。
【讨论】:
如果 CV1.CALENDAR_DAY 也有小时和秒怎么办? @BigMike:那么 CALENDAR_DAY 是一个非常糟糕的名称 :-) 太糟糕了,Oracle 没有真正的DATE
数据类型,而只有日期时间类型他们调用 DATE。
我已经更新了我的笔记——这个设计不是自愿的。我的主要问题是为什么这适用于 INNER 而不是 LEFT。这是某种 Oracle 特定问题,因为我将在 Teradata 中工作。
@ThorstenKettner 这就是为什么我更喜欢在比较时添加一个明确的 TRUNC(date_column),如果你知道时间部分总是 00:00:00,你可以跳过 trunc以上是关于Oracle Left Join 导致单行子查询返回多行错误的主要内容,如果未能解决你的问题,请参考以下文章
资深java工程师写mysql表子查询left join导致大事务-线上事故
MySQL 的子查询和left join的比较,啥时候用子查询效率高,啥时候用left join效率高?