【问题标题】:How to compare two SELECT subqueries by using the BETWEEN operator?如何使用 BETWEEN 运算符比较两个 SELECT 子查询?
【发布时间】:2016-10-07 23:14:16
【问题描述】:

我正在使用 Oracle Database 12c 企业版。

表格如下所示:http://i.stack.imgur.com/gL2L6.jpg

该表显示了不同股票的股票价格,每天有不同的 ID (WKN)、起始价 (Start)、最高价 (Hoch)、最低价 (Tief) 和收盘价 (Schluss)日期(基准)。我现在想直接在 SQL 中计算 90 天线。它是通过确定90天内每一天的过去90天收盘价的算术平均值来计算的。

我尝试使用以下 SQL 语句来计算:

SELECT SUM(SCHLUSSPREIS) / 90 AS TAGESLINIE FROM KURS WHERE DATUM BETWEEN
  (SELECT DATUM FROM KURS WHERE WKN = 2 AND DATUM BETWEEN
    (SELECT MAX(DATUM) - 179 FROM KURS) AND
    (SELECT MAX(DATUM) - 90 FROM KURS) ORDER BY DATUM ASC)
  AND (SELECT DATUM FROM KURS WHERE WKN = 2 AND DATUM BETWEEN
   (SELECT MAX(DATUM) - 89 FROM KURS) AND
   (SELECT MAX(DATUM) FROM KURS) ORDER BY DATUM ASC)
;

为了让您更好地了解这个令人困惑的陈述,我创建了以下方案:http://i.stack.imgur.com/XjYXf.jpg

两者,第一个子查询...

(SELECT DATUM FROM KURS WHERE WKN = 2 AND DATUM BETWEEN
  (SELECT MAX(DATUM) - 179 FROM KURS) AND
  (SELECT MAX(DATUM) - 90 FROM KURS) ORDER BY DATUM ASC)

...和第二个子查询...

(SELECT DATUM FROM KURS WHERE WKN = 2 AND DATUM BETWEEN
  (SELECT MAX(DATUM) - 89 FROM KURS) AND
  (SELECT MAX(DATUM) FROM KURS) ORDER BY DATUM ASC)

...确实返回相同数量的日期列表 (90)。

第一个子查询列表中的第一个日期属于第二个子查询列表中的第一个日期,第一个子查询列表中的第二个日期属于第二个子查询列表中的第二个日期,以此类推.(上面的比较方案)。我现在希望我的 SQL 语句总结每个期间(从第一个日期(列表 1)到第一个日期(列表 2)等)之间的所有收盘价,并将其除以 90 以获得算术平均值,直到两个列表是空的。

但是,如果我运行它,我会收到以下错误消息:

ERROR at line 1:
ORA-00907: missing right parenthesis

ERROR at line 1:
ORA-01427: single row subquery returns more than one row

知道如何直接在 SQL 中执行类似的操作吗?

感谢您的帮助-谢谢! :-)

【问题讨论】:

  • 您可以编写一个 SQL 函数来计算 90 天的平均值。它接受 WKN 和结束日期作为参数,并返回平均值。将此与主查询分开测试并使其正常工作。然后你从你的主 SQL 选择中调用这个函数。
  • 我必须为大学做这个,我们不允许使用用户定义的 SQL 函数。我将尝试使用 join 和 coalesce() 函数来解决它。

标签: sql select subquery between oracle12c


【解决方案1】:

SUM 不是 SQL 中唯一可用的聚合函数。 在这里,您可能想改用AVG

SELECT *
FROM (
  SELECT
     DATUM,
     AVG(SCHLUSSPREIS) OVER (ORDER BY DATUM rows BETWEEN 89 PRECEDING AND CURRENT ROW) AS TAGESLINIE
  FROM KURS
  WHERE WKN = 2
  ORDER BY DATUM DESC
) Moving_Average
WHERE ROWNUM <= 90;

【讨论】:

  • 感谢您的提示,但这实际上不是我的问题。问题是我在 BETWEEN 语句之间有两个子查询,它们都重新调整了日期列表,例如 this。我现在希望 BETWEEN 语句将第一个列表中的每个日期与第二个列表中在订单上具有相同位置的日期进行比较。但是由于错误消息(单行子查询返回多行),我认为这在 BETWEEN 中是不可能的。那么如何在没有用户定义的 SQL 函数的情况下做这样的事情呢?
  • 那个:Oracle moving average 响铃了吗?
  • 我承认,我的问题有点混乱。我希望 SQL 从某个股票中计算 90 天线,从该股票的当前最高可用日期开始(这就是我使用 MAX(DATUM) 的原因)。但为了做到这一点,您必须确定 90 天内每一天的收盘价的算术平均值。所以最后你应该得到 90 种不同的算术方法。假设 MAX(DATUM) 是 31-DEC-15。然后,将根据 MA​​X(DATUM) - 89 和 MAX(DATUM) 之间的所有收盘价计算第一个算术平均值。 [继续下一条评论]
  • MAX(DATUM) - 90 和 MAX(DATUM) - 1 之间所有收盘价的第二个算术平均值。MAX(DATUM) - 91 天和 MAX(DATUM) 之间所有收盘价的第三个- 2 次等,直到完成所有 90 天。
  • 谢谢!只有两个小错误:首先,在这种特定情况下,AVG 不是 GROUP BY 表达式,因此只需将其删除。其次,该语句将返回错误的结果,因为您在 OVER 子句中写了 90 而不是 89。因此,SQL 使用 91 个值进行计算,而不是 90 个。其他一切都很好。再次非常感谢您!
猜你喜欢
  • 2011-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-20
  • 1970-01-01
  • 2013-05-28
  • 2011-04-15
  • 1970-01-01
相关资源
最近更新 更多