【问题标题】:SQL command not properly ended, concerning with table aliasesSQL 命令未正确结束,与表别名有关
【发布时间】:2015-03-01 20:33:46
【问题描述】:

我知道 oracle 不允许使用 AS 命令来使用表别名,因此有人建议我使用如下解决方案。

SELECT Temp.avgsale
FROM (SELECT o.received, AVG(p.price*d.qty+d.sfee) avgsale
     FROM orders o, parts p, odetails d
     GROUP BY o.received) Temp
WHERE Temp.avgsale=(SELECT MIN(Temp.avgsale) FROM Temp);

但是,当我运行它时出现以下错误:ERROR at line 4: ORA-00942: table or view does not exist。当我尝试在SELECT 查询的开头设置别名时,我也会遇到类似的错误:Temp (SELECT ...)。任何帮助将不胜感激,因为我在查询有什么问题时遇到了麻烦。

【问题讨论】:

  • Bad habits to kick : using old-style JOINs - 旧式 逗号分隔的表格列表 样式已替换为 ANSI 中的 proper ANSI JOIN 语法-92 SQL 标准(20 多年前),不鼓励使用它
  • 我认为 Oracle 自 2001 年(9i 发布时)以来仅支持 ANSI JOIN 语法。所以旧式的 JOIN 已经过时了 14 年。 :)

标签: sql oracle alias


【解决方案1】:

问题是当解析 where 子句中的子查询时,表别名 temp 可能尚未定义。您可以改用公用表表达式:

WITH Temp AS (
    SELECT o.received, AVG(p.price*d.qty+d.sfee) avgsale
    FROM orders o, parts p, odetails d
    GROUP BY o.received
    )

SELECT Temp.avgsale
FROM Temp
WHERE Temp.avgsale = (SELECT MIN(Temp.avgsale) FROM Temp);

看起来查询还有另一个问题;它缺少所需的订单、零件和详细信息表之间的连接。你可能想要这样的东西:

WITH Temp AS (
    SELECT o.received, AVG(p.price*d.qty+d.sfee) avgsale
    FROM orders o
    JOIN odetails od ON o.orderid = od.orderid
    JOIN parts p ON p.partid = od.partid 
    GROUP BY o.received
    )

SELECT Temp.avgsale
FROM Temp
WHERE Temp.avgsale = (SELECT MIN(Temp.avgsale) FROM Temp);

请注意,我只是在猜测您的列名是什么,因为您没有在问题中包含有关它的任何信息。

另外,也许您希望订单匹配 min(temp.avgsale) 而不仅仅是 min()?如果是这样,将最后一部分更改为:

SELECT Temp.received, Temp.avgsale
FROM Temp
WHERE Temp.avgsale = (SELECT MIN(Temp.avgsale) FROM Temp);

这个查询对我来说更有意义。

【讨论】:

  • 非常有帮助。谢谢。
  • @lee1129 乐于助人:)
  • WITH 前面的分号是不必要的
  • @DavidFaber 确实,但它不会受到伤害,我通常将其放入以确保任何先前的批次都已终止(但也许 Oracle 不需要 - MSSQL 确实需要):)跨度>
【解决方案2】:

您似乎想要获取给定日期(received?是日期吗?)的订单平均销售额是最低平均销售额的数据?您可以使用窗口(分析)函数来执行此操作。请注意 - 我猜测您的连接条件如下,因为您的原始查询使用笛卡尔连接。

SELECT received, avgsale FROM (
    SELECT received, avgsale, RANK() OVER ( ORDER BY avgsale ) AS rn
      FROM (
        SELECT o.received, AVG(p.price * d.qty + d.sfee) AS avgsale
          FROM orders o INNER JOIN odetails d
            ON o.order_id = d.order_id
         INNER JOIN parts p
            ON d.part_id = p.part_id
         GROUP BY o.received
    )
) WHERE rn = 1;

请注意,这将检索received 的所有值,以及相应的平均销售额,其中平均销售额等于最小值。如果您只想要一行,请使用ROW_NUMBER() 代替RANK()

如果你更喜欢用 CTE 来写,那么你可以这样做:

WITH temp AS (
    SELECT o.received, AVG(p.price * d.qty + d.sfee) AS avgsale
      FROM orders o INNER JOIN odetails d
        ON o.order_id = d.order_id
     INNER JOIN parts p
        ON d.part_id = p.part_id
     GROUP BY o.received
)
SELECT received, avgsale FROM (
    SELECT received, avgsale, RANK() OVER ( ORDER BY avgsale ) AS rn
      FROM temp
) WHERE rn = 1;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-21
    • 1970-01-01
    • 2013-01-05
    相关资源
    最近更新 更多