在子查询中使用partition子句

时间:2013-09-20 05:24:57

标签: teradata partition

对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'关键字之间。

1 个答案:

答案 0 :(得分:4)

您不能在子查询中使用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 View”,因此命名也可能令人困惑:

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