【问题标题】:Using partition clause in the subquery在子查询中使用分区子句
【发布时间】:2013-09-20 21:06:48
【问题描述】:

我是 TD 新手,需要一些关于以下查询的帮助。

我们有一个查询,它的 from 子句如下所示:

`*sel *
FROM 
V_ACOR  ACOR,
V_ORTR ORTR,
V_MSAC MSAC,
V_MSRC MSRC,
V_REOR REOR
WHERE 
ACOR.ORDER_ID = ORTR.ORDER_ID
AND 
(SELECT MIN(ARRIVE_DATE_ORTR)  AS ARRIVE_DATE FROM V_ORTR )
BETWEEN  MSAC.BEGIN_DATE AND  MSAC.END_DATE
AND 
(SELECT MIN(ARRIVE_DATE_ORTR)  AS ARRIVE_DATE FROM V_ORTR )
BETWEEN  MSRC.BEGIN_DATE AND  MSRC.END_DATE
AND  
(SELECT MIN(ARRIVE_DATE_REOR)  AS ARRIVE_DATE FROM V_REOR )
BETWEEN  MSAC.BEGIN_DATE AND  MSAC.END_DATE
AND 
(SELECT MIN(ARRIVE_DATE_REOR)  AS ARRIVE_DATE FROM V_REOR )
BETWEEN  MSRC.BEGIN_DATE AND  MSRC.END_DATE*`

现在的问题是,在所有情况下,MIN(ARRIVE_DATE) 都会给我所有条目的最小值。我们的要求是根据 ORDER_ID 获取最小日期。因此,我们尝试使用以下代替 MIN(ARRIVE_DATE):

`(SELECT ARRIVE_DATE FROM V_ORTR  
qualify row_NUMBER() over (PARTITION  by ORDER_ID order by ARRIVE_DATE ASC) = 1
)BETWEEN  MSAC.BEGIN_DATE AND  MSAC.END_DATE`

这是显示错误:

子查询中不允许使用有序分析函数。

我们也尝试了以下方法:

`*sel * from 
(
sel A.*
from (sel * FROM V_ORTR
QUALIFY row_NUMBER() over (PARTITION  by ORTR.ORDER_ID order by ORTR.ARRIVE_DATE ASC)=1
) A ,
sel B.*
from (sel * FROM V_REOR
QUALIFY row_NUMBER() over (PARTITION  by REOR.ORDER_ID order by REOR.ARRIVE_DATE_ORDR_TR ASC)=1 
)B ,
V_ACOR,
V_MSAC,
V_MSRC
WHERE 
ACOR.ORDER_ID_ORDR = A.ORDER_ID
AND A.ARRIVE_DATE_ORTR BETWEEN MSAC.BEGIN_DATE AND MSAC.END_DATE
AND A.ARRIVE_DATE_ORTR BETWEEN MSRC.BEGIN_DATE AND MSRC.END_DATE
AND B.ARRIVE_DATE_REOR BETWEEN MSAC.BEGIN_DATE AND MSAC.END_DATE
AND B.ARRIVE_DATE_REOR BETWEEN MSRC.BEGIN_DATE AND MSRC.END_DATE
)*`

这也给出了以下错误:

语法错误,应为名称或 Unicode 分隔标识符或 '(' 介于 '.' 和 'sel' 关键字之间。

【问题讨论】:

  • 您使用的是哪个 DBMS(和版本)?后格雷斯?甲骨文? SQL 服务器? DB2?
  • 感谢您的回复。我们使用的是 Teradata 版本 13

标签: teradata partition


【解决方案1】:

您不能在子查询中使用 OLAP 函数,因为它们可能相互关联。处理这个特定错误有一个技巧:将它移到子查询中的派生表中(无法关联到派生表中):

WHERE   
 (
   SELECT * 
   FROM
    (
      SELECT ARRIVE_DATE 
      FROM V_ORTR  
      QUALIFY ROW_NUMBER() 
      OVER (PARTITION  BY ORDER_ID ORDER BY ARRIVE_DATE ASC) = 1
    ) AS dt
 ) BETWEEN  MSAC.BEGIN_DATE AND  MSAC.END_DATE

但这不起作用,因为它返回多行带有

"3669 子查询返回了多个值"

您的第二次尝试有一些语法错误。另外,您不需要将 OLAP 函数嵌套在派生表中,因为它已经在派生表中。一些(或者很多人)将“派生表”称为“子查询”,在 Oracle 中它是“Inlie 视图”,因此命名也可能令人困惑:

SELECT * 
FROM 
 (
   SELECT * FROM V_ORTR
   QUALIFY ROW_NUMBER() OVER (PARTITION  BY ORTR.ORDER_ID ORDER BY ORTR.ARRIVE_DATE ASC) = 1
 ) A ,
 (
   SELECT * FROM V_REOR
   QUALIFY ROW_NUMBER() OVER (PARTITION  BY REOR.ORDER_ID ORDER BY REOR.ARRIVE_DATE_ORDR_TR ASC) = 1 
 ) B,
   V_ACOR,
   V_MSAC,
   V_MSRC
WHERE 
  ACOR.ORDER_ID_ORDR = A.ORDER_ID
AND A.ARRIVE_DATE_ORTR BETWEEN MSAC.BEGIN_DATE AND MSAC.END_DATE
AND A.ARRIVE_DATE_ORTR BETWEEN MSRC.BEGIN_DATE AND MSRC.END_DATE
AND B.ARRIVE_DATE_REOR BETWEEN MSAC.BEGIN_DATE AND MSAC.END_DATE
AND B.ARRIVE_DATE_REOR BETWEEN MSRC.BEGIN_DATE AND MSRC.END_DATE

但是你确定这些都是加入条件吗?我希望有一些额外的条件,至少 A.ORDER_ID = B.ORDER_ID

【讨论】:

  • 感谢您的回复。我们还有更多的连接。是的,OEDER_ID 的连接也在那里。
猜你喜欢
  • 2020-02-08
  • 2018-09-12
  • 1970-01-01
  • 2021-11-16
  • 1970-01-01
  • 2018-04-14
  • 2014-09-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多